@ -627,3 +627,143 @@ U_BOOT_CMD(
" boot Linux zImage image from memory " , bootz_help_text
) ;
# endif /* CONFIG_CMD_BOOTZ */
# ifdef CONFIG_CMD_BOOTI
/* See Documentation/arm64/booting.txt in the Linux kernel */
struct Image_header {
uint32_t code0 ; /* Executable code */
uint32_t code1 ; /* Executable code */
uint64_t text_offset ; /* Image load offset, LE */
uint64_t image_size ; /* Effective Image size, LE */
uint64_t res1 ; /* reserved */
uint64_t res2 ; /* reserved */
uint64_t res3 ; /* reserved */
uint64_t res4 ; /* reserved */
uint32_t magic ; /* Magic number */
uint32_t res5 ;
} ;
# define LINUX_ARM64_IMAGE_MAGIC 0x644d5241
static int booti_setup ( bootm_headers_t * images )
{
struct Image_header * ih ;
uint64_t dst ;
ih = ( struct Image_header * ) map_sysmem ( images - > ep , 0 ) ;
if ( ih - > magic ! = le32_to_cpu ( LINUX_ARM64_IMAGE_MAGIC ) ) {
puts ( " Bad Linux ARM64 Image magic! \n " ) ;
return 1 ;
}
if ( ih - > image_size = = 0 ) {
puts ( " Image lacks image_size field, assuming 16MiB \n " ) ;
ih - > image_size = ( 16 < < 20 ) ;
}
/*
* If we are not at the correct run - time location , set the new
* correct location and then move the image there .
*/
dst = gd - > bd - > bi_dram [ 0 ] . start + le32_to_cpu ( ih - > text_offset ) ;
if ( images - > ep ! = dst ) {
void * src ;
debug ( " Moving Image from 0x%lx to 0x%llx \n " , images - > ep , dst ) ;
src = ( void * ) images - > ep ;
images - > ep = dst ;
memmove ( ( void * ) dst , src , le32_to_cpu ( ih - > image_size ) ) ;
}
return 0 ;
}
/*
* Image booting support
*/
static int booti_start ( cmd_tbl_t * cmdtp , int flag , int argc ,
char * const argv [ ] , bootm_headers_t * images )
{
int ret ;
struct Image_header * ih ;
ret = do_bootm_states ( cmdtp , flag , argc , argv , BOOTM_STATE_START ,
images , 1 ) ;
/* Setup Linux kernel Image entry point */
if ( ! argc ) {
images - > ep = load_addr ;
debug ( " * kernel: default image load address = 0x%08lx \n " ,
load_addr ) ;
} else {
images - > ep = simple_strtoul ( argv [ 0 ] , NULL , 16 ) ;
debug ( " * kernel: cmdline image address = 0x%08lx \n " ,
images - > ep ) ;
}
ret = booti_setup ( images ) ;
if ( ret ! = 0 )
return 1 ;
ih = ( struct Image_header * ) map_sysmem ( images - > ep , 0 ) ;
lmb_reserve ( & images - > lmb , images - > ep , le32_to_cpu ( ih - > image_size ) ) ;
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
* have a header that provide this informaiton .
*/
if ( bootm_find_ramdisk_fdt ( flag , argc , argv ) )
return 1 ;
return 0 ;
}
int do_booti ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
int ret ;
/* Consume 'booti' */
argc - - ; argv + + ;
if ( booti_start ( cmdtp , flag , argc , argv , & images ) )
return 1 ;
/*
* We are doing the BOOTM_STATE_LOADOS state ourselves , so must
* disable interrupts ourselves
*/
bootm_disable_interrupts ( ) ;
images . os . os = IH_OS_LINUX ;
ret = do_bootm_states ( cmdtp , flag , argc , argv ,
BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
BOOTM_STATE_OS_GO ,
& images , 1 ) ;
return ret ;
}
# ifdef CONFIG_SYS_LONGHELP
static char booti_help_text [ ] =
" [addr [initrd[:size]] [fdt]] \n "
" - boot Linux Image stored in memory \n "
" \t The argument 'initrd' is optional and specifies the address \n "
" \t of the initrd in memory. The optional argument ':size' allows \n "
" \t specifying the size of RAW initrd. \n "
# if defined(CONFIG_OF_LIBFDT)
" \t Since booting a Linux kernelrequires a flat device-tree \n "
" \t a third argument is required which is the address of the \n "
" \t device-tree blob. To boot that kernel without an initrd image, \n "
" \t use a '-' for the second argument. \n "
# endif
" " ;
# endif
U_BOOT_CMD (
booti , CONFIG_SYS_MAXARGS , 1 , do_booti ,
" boot arm64 Linux Image image from memory " , booti_help_text
) ;
# endif /* CONFIG_CMD_BOOTI */