/*
* ( C ) Copyright 2000 - 2009
* Wolfgang Denk , DENX Software Engineering , wd @ denx . de .
*
* SPDX - License - Identifier : GPL - 2.0 +
*/
/*
* Boot support
*/
# include <common.h>
# include <bootm.h>
# include <command.h>
# include <environment.h>
# include <errno.h>
# include <image.h>
# include <lmb.h>
# include <malloc.h>
# include <mapmem.h>
# include <nand.h>
# include <asm/byteorder.h>
# include <linux/compiler.h>
# include <linux/ctype.h>
# include <linux/err.h>
# include <u-boot/zlib.h>
DECLARE_GLOBAL_DATA_PTR ;
# if defined(CONFIG_CMD_IMI)
static int image_info ( unsigned long addr ) ;
# endif
# if defined(CONFIG_CMD_IMLS)
# include <flash.h>
# include <mtd/cfi_flash.h>
extern flash_info_t flash_info [ ] ; /* info for FLASH chips */
# endif
# if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
static int do_imls ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] ) ;
# endif
bootm_headers_t images ; /* pointers to os/initrd/fdt images */
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
/* we overload the cmd field with our state machine info instead of a
* function pointer */
static cmd_tbl_t cmd_bootm_sub [ ] = {
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
U_BOOT_CMD_MKENT ( start , 0 , 1 , ( void * ) BOOTM_STATE_START , " " , " " ) ,
U_BOOT_CMD_MKENT ( loados , 0 , 1 , ( void * ) BOOTM_STATE_LOADOS , " " , " " ) ,
# ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
U_BOOT_CMD_MKENT ( ramdisk , 0 , 1 , ( void * ) BOOTM_STATE_RAMDISK , " " , " " ) ,
# endif
# ifdef CONFIG_OF_LIBFDT
U_BOOT_CMD_MKENT ( fdt , 0 , 1 , ( void * ) BOOTM_STATE_FDT , " " , " " ) ,
# endif
U_BOOT_CMD_MKENT ( cmdline , 0 , 1 , ( void * ) BOOTM_STATE_OS_CMDLINE , " " , " " ) ,
U_BOOT_CMD_MKENT ( bdt , 0 , 1 , ( void * ) BOOTM_STATE_OS_BD_T , " " , " " ) ,
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
U_BOOT_CMD_MKENT ( prep , 0 , 1 , ( void * ) BOOTM_STATE_OS_PREP , " " , " " ) ,
U_BOOT_CMD_MKENT ( fake , 0 , 1 , ( void * ) BOOTM_STATE_OS_FAKE_GO , " " , " " ) ,
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
U_BOOT_CMD_MKENT ( go , 0 , 1 , ( void * ) BOOTM_STATE_OS_GO , " " , " " ) ,
} ;
static int do_bootm_subcommand ( cmd_tbl_t * cmdtp , int flag , int argc ,
char * const argv [ ] )
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
{
int ret = 0 ;
long state ;
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
cmd_tbl_t * c ;
c = find_cmd_tbl ( argv [ 0 ] , & cmd_bootm_sub [ 0 ] , ARRAY_SIZE ( cmd_bootm_sub ) ) ;
argc - - ; argv + + ;
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
if ( c ) {
state = ( long ) c - > cmd ;
if ( state = = BOOTM_STATE_START )
state | = BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER ;
} else {
/* Unrecognized command */
return CMD_RET_USAGE ;
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
}
if ( ( ( state & BOOTM_STATE_START ) ! = BOOTM_STATE_START ) & &
images . state > = state ) {
printf ( " Trying to execute a command out of order \n " ) ;
return CMD_RET_USAGE ;
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
}
ret = do_bootm_states ( cmdtp , flag , argc , argv , state , & images , 0 ) ;
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
return ret ;
}
/*******************************************************************/
/* bootm - boot application image from image in memory */
/*******************************************************************/
int do_bootm ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
# ifdef CONFIG_NEEDS_MANUAL_RELOC
static int relocated = 0 ;
if ( ! relocated ) {
int i ;
/* relocate names of sub-command table */
for ( i = 0 ; i < ARRAY_SIZE ( cmd_bootm_sub ) ; i + + )
cmd_bootm_sub [ i ] . name + = gd - > reloc_off ;
relocated = 1 ;
}
# endif
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
/* determine if we have a sub command */
argc - - ; argv + + ;
if ( argc > 0 ) {
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
char * endp ;
simple_strtoul ( argv [ 0 ] , & endp , 16 ) ;
/* endp pointing to NULL means that argv[0] was just a
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
* valid number , pass it along to the normal bootm processing
*
* If endp is ' : ' or ' # ' assume a FIT identifier so pass
* along for normal processing .
*
* Right now we assume the first arg should never be ' - '
*/
if ( ( * endp ! = 0 ) & & ( * endp ! = ' : ' ) & & ( * endp ! = ' # ' ) )
return do_bootm_subcommand ( cmdtp , flag , argc , argv ) ;
}
return do_bootm_states ( cmdtp , flag , argc , argv , BOOTM_STATE_START |
BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
BOOTM_STATE_LOADOS |
# if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
BOOTM_STATE_OS_CMDLINE |
# endif
BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
BOOTM_STATE_OS_GO , & images , 1 ) ;
}
int bootm_maybe_autostart ( cmd_tbl_t * cmdtp , const char * cmd )
{
const char * ep = getenv ( " autostart " ) ;
if ( ep & & ! strcmp ( ep , " yes " ) ) {
char * local_args [ 2 ] ;
local_args [ 0 ] = ( char * ) cmd ;
local_args [ 1 ] = NULL ;
printf ( " Automatic boot of image at addr 0x%08lX ... \n " , load_addr ) ;
return do_bootm ( cmdtp , 0 , 1 , local_args ) ;
}
return 0 ;
}
# ifdef CONFIG_SYS_LONGHELP
static char bootm_help_text [ ] =
" [addr [arg ...]] \n - boot application image stored in memory \n "
" \t passing arguments 'arg ...'; when booting a Linux kernel, \n "
" \t 'arg' can be the address of an initrd image \n "
# if defined(CONFIG_OF_LIBFDT)
" \t When booting a Linux kernel which requires 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. If you do not pass a third \n "
" \t a bd_info struct will be passed instead \n "
# endif
# if defined(CONFIG_FIT)
" \t \n For the new multi component uImage format (FIT) addresses \n "
" \t must be extened to include component or configuration unit name: \n "
" \t addr:<subimg_uname> - direct component image specification \n "
" \t addr#<conf_uname> - configuration specification \n "
" \t Use iminfo command to get the list of existing component \n "
" \t images and configurations. \n "
# endif
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
" \n Sub-commands to do part of the bootm sequence. The sub-commands "
" must be \n "
" issued in the order below (it's ok to not issue all sub-commands): \n "
" \t start [addr [arg ...]] \n "
" \t loados - load OS image \n "
# if defined(CONFIG_SYS_BOOT_RAMDISK_HIGH)
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
" \t ramdisk - relocate initrd, set env initrd_start/initrd_end \n "
# endif
# if defined(CONFIG_OF_LIBFDT)
" \t fdt - relocate flat device tree \n "
# endif
" \t cmdline - OS specific command line processing/setup \n "
" \t bdt - OS specific bd_t processing \n "
bootm: Add subcommands
Add the ability to break the steps of the bootm command into several
subcommands: start, loados, ramdisk, fdt, bdt, cmdline, prep, go.
This allows us to do things like manipulate device trees before
they are passed to a booting kernel or setup memory for a secondary
core in multicore situations.
Not all OS types support all subcommands (currently only start, loados,
ramdisk, fdt, and go are supported).
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 years ago
" \t prep - OS specific prep before relocation or go \n "
# if defined(CONFIG_TRACE)
" \t fake - OS specific fake start without go \n "
# endif
" \t go - start OS " ;
# endif
U_BOOT_CMD (
bootm , CONFIG_SYS_MAXARGS , 1 , do_bootm ,
" boot application image from memory " , bootm_help_text
) ;
/*******************************************************************/
/* bootd - boot default image */
/*******************************************************************/
# if defined(CONFIG_CMD_BOOTD)
int do_bootd ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
return run_command ( getenv ( " bootcmd " ) , flag ) ;
}
U_BOOT_CMD (
boot , 1 , 1 , do_bootd ,
" boot default, i.e., run 'bootcmd' " ,
" "
) ;
/* keep old command name "bootd" for backward compatibility */
U_BOOT_CMD (
bootd , 1 , 1 , do_bootd ,
" boot default, i.e., run 'bootcmd' " ,
" "
) ;
# endif
/*******************************************************************/
/* iminfo - print header info for a requested image */
/*******************************************************************/
# if defined(CONFIG_CMD_IMI)
static int do_iminfo ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
int arg ;
ulong addr ;
int rcode = 0 ;
if ( argc < 2 ) {
return image_info ( load_addr ) ;
}
for ( arg = 1 ; arg < argc ; + + arg ) {
addr = simple_strtoul ( argv [ arg ] , NULL , 16 ) ;
if ( image_info ( addr ) ! = 0 )
rcode = 1 ;
}
return rcode ;
}
static int image_info ( ulong addr )
{
void * hdr = ( void * ) addr ;
printf ( " \n ## Checking Image at %08lx ... \n " , addr ) ;
switch ( genimg_get_format ( hdr ) ) {
# if defined(CONFIG_IMAGE_FORMAT_LEGACY)
case IMAGE_FORMAT_LEGACY :
puts ( " Legacy image found \n " ) ;
if ( ! image_check_magic ( hdr ) ) {
puts ( " Bad Magic Number \n " ) ;
return 1 ;
}
if ( ! image_check_hcrc ( hdr ) ) {
puts ( " Bad Header Checksum \n " ) ;
return 1 ;
}
image_print_contents ( hdr ) ;
puts ( " Verifying Checksum ... " ) ;
if ( ! image_check_dcrc ( hdr ) ) {
puts ( " Bad Data CRC \n " ) ;
return 1 ;
}
puts ( " OK \n " ) ;
return 0 ;
# endif
# if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT :
puts ( " FIT image found \n " ) ;
if ( ! fit_check_format ( hdr ) ) {
puts ( " Bad FIT image format! \n " ) ;
return 1 ;
}
fit_print_contents ( hdr ) ;
if ( ! fit_all_image_verify ( hdr ) ) {
puts ( " Bad hash in FIT image! \n " ) ;
return 1 ;
}
return 0 ;
# endif
default :
puts ( " Unknown image format! \n " ) ;
break ;
}
return 1 ;
}
U_BOOT_CMD (
iminfo , CONFIG_SYS_MAXARGS , 1 , do_iminfo ,
" print header information for application image " ,
" addr [addr ...] \n "
" - print header information for application image starting at \n "
" address 'addr' in memory; this includes verification of the \n "
" image contents (magic number, header and payload checksums) "
) ;
# endif
/*******************************************************************/
/* imls - list all images found in flash */
/*******************************************************************/
# if defined(CONFIG_CMD_IMLS)
static int do_imls_nor ( void )
{
flash_info_t * info ;
int i , j ;
void * hdr ;
for ( i = 0 , info = & flash_info [ 0 ] ;
i < CONFIG_SYS_MAX_FLASH_BANKS ; + + i , + + info ) {
if ( info - > flash_id = = FLASH_UNKNOWN )
goto next_bank ;
for ( j = 0 ; j < info - > sector_count ; + + j ) {
hdr = ( void * ) info - > start [ j ] ;
if ( ! hdr )
goto next_sector ;
switch ( genimg_get_format ( hdr ) ) {
# if defined(CONFIG_IMAGE_FORMAT_LEGACY)
case IMAGE_FORMAT_LEGACY :
if ( ! image_check_hcrc ( hdr ) )
goto next_sector ;
printf ( " Legacy Image at %08lX: \n " , ( ulong ) hdr ) ;
image_print_contents ( hdr ) ;
puts ( " Verifying Checksum ... " ) ;
if ( ! image_check_dcrc ( hdr ) ) {
puts ( " Bad Data CRC \n " ) ;
} else {
puts ( " OK \n " ) ;
}
break ;
# endif
# if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT :
if ( ! fit_check_format ( hdr ) )
goto next_sector ;
printf ( " FIT Image at %08lX: \n " , ( ulong ) hdr ) ;
fit_print_contents ( hdr ) ;
break ;
# endif
default :
goto next_sector ;
}
next_sector : ;
}
next_bank : ;
}
return 0 ;
}
# endif
# if defined(CONFIG_CMD_IMLS_NAND)
static int nand_imls_legacyimage ( nand_info_t * nand , int nand_dev , loff_t off ,
size_t len )
{
void * imgdata ;
int ret ;
imgdata = malloc ( len ) ;
if ( ! imgdata ) {
printf ( " May be a Legacy Image at NAND device %d offset %08llX: \n " ,
nand_dev , off ) ;
printf ( " Low memory(cannot allocate memory for image) \n " ) ;
return - ENOMEM ;
}
ret = nand_read_skip_bad ( nand , off , & len ,
imgdata ) ;
if ( ret < 0 & & ret ! = - EUCLEAN ) {
free ( imgdata ) ;
return ret ;
}
if ( ! image_check_hcrc ( imgdata ) ) {
free ( imgdata ) ;
return 0 ;
}
printf ( " Legacy Image at NAND device %d offset %08llX: \n " ,
nand_dev , off ) ;
image_print_contents ( imgdata ) ;
puts ( " Verifying Checksum ... " ) ;
if ( ! image_check_dcrc ( imgdata ) )
puts ( " Bad Data CRC \n " ) ;
else
puts ( " OK \n " ) ;
free ( imgdata ) ;
return 0 ;
}
static int nand_imls_fitimage ( nand_info_t * nand , int nand_dev , loff_t off ,
size_t len )
{
void * imgdata ;
int ret ;
imgdata = malloc ( len ) ;
if ( ! imgdata ) {
printf ( " May be a FIT Image at NAND device %d offset %08llX: \n " ,
nand_dev , off ) ;
printf ( " Low memory(cannot allocate memory for image) \n " ) ;
return - ENOMEM ;
}
ret = nand_read_skip_bad ( nand , off , & len ,
imgdata ) ;
if ( ret < 0 & & ret ! = - EUCLEAN ) {
free ( imgdata ) ;
return ret ;
}
if ( ! fit_check_format ( imgdata ) ) {
free ( imgdata ) ;
return 0 ;
}
printf ( " FIT Image at NAND device %d offset %08llX: \n " , nand_dev , off ) ;
fit_print_contents ( imgdata ) ;
free ( imgdata ) ;
return 0 ;
}
static int do_imls_nand ( void )
{
nand_info_t * nand ;
int nand_dev = nand_curr_device ;
size_t len ;
loff_t off ;
u32 buffer [ 16 ] ;
if ( nand_dev < 0 | | nand_dev > = CONFIG_SYS_MAX_NAND_DEVICE ) {
puts ( " \n No NAND devices available \n " ) ;
return - ENODEV ;
}
printf ( " \n " ) ;
for ( nand_dev = 0 ; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE ; nand_dev + + ) {
nand = & nand_info [ nand_dev ] ;
if ( ! nand - > name | | ! nand - > size )
continue ;
for ( off = 0 ; off < nand - > size ; off + = nand - > erasesize ) {
const image_header_t * header ;
int ret ;
if ( nand_block_isbad ( nand , off ) )
continue ;
len = sizeof ( buffer ) ;
ret = nand_read ( nand , off , & len , ( u8 * ) buffer ) ;
if ( ret < 0 & & ret ! = - EUCLEAN ) {
printf ( " NAND read error %d at offset %08llX \n " ,
ret , off ) ;
continue ;
}
switch ( genimg_get_format ( buffer ) ) {
# if defined(CONFIG_IMAGE_FORMAT_LEGACY)
case IMAGE_FORMAT_LEGACY :
header = ( const image_header_t * ) buffer ;
len = image_get_image_size ( header ) ;
nand_imls_legacyimage ( nand , nand_dev , off , len ) ;
break ;
# endif
# if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT :
len = fit_get_size ( buffer ) ;
nand_imls_fitimage ( nand , nand_dev , off , len ) ;
break ;
# endif
}
}
}
return 0 ;
}
# endif
# if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
static int do_imls ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
int ret_nor = 0 , ret_nand = 0 ;
# if defined(CONFIG_CMD_IMLS)
ret_nor = do_imls_nor ( ) ;
# endif
# if defined(CONFIG_CMD_IMLS_NAND)
ret_nand = do_imls_nand ( ) ;
# endif
if ( ret_nor )
return ret_nor ;
if ( ret_nand )
return ret_nand ;
return ( 0 ) ;
}
U_BOOT_CMD (
imls , 1 , 1 , do_imls ,
" list all images found in flash " ,
" \n "
" - Prints information about all images found at sector/block \n "
" boundaries in nor/nand flash. "
) ;
# endif
# ifdef CONFIG_CMD_BOOTZ
int __weak bootz_setup ( ulong image , ulong * start , ulong * end )
{
/* Please define bootz_setup() for your platform */
puts ( " Your platform's zImage format isn't supported yet! \n " ) ;
return - 1 ;
}
/*
* zImage booting support
*/
static int bootz_start ( cmd_tbl_t * cmdtp , int flag , int argc ,
char * const argv [ ] , bootm_headers_t * images )
{
int ret ;
ulong zi_start , zi_end ;
ret = do_bootm_states ( cmdtp , flag , argc , argv , BOOTM_STATE_START ,
images , 1 ) ;
/* Setup Linux kernel zImage 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 = bootz_setup ( images - > ep , & zi_start , & zi_end ) ;
if ( ret ! = 0 )
return 1 ;
lmb_reserve ( & images - > lmb , images - > ep , zi_end - zi_start ) ;
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
* have a header that provide this informaiton .
*/
if ( bootm_find_images ( flag , argc , argv ) )
return 1 ;
return 0 ;
}
int do_bootz ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
int ret ;
/* Consume 'bootz' */
argc - - ; argv + + ;
if ( bootz_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 bootz_help_text [ ] =
" [addr [initrd[:size]] [fdt]] \n "
" - boot Linux zImage 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 When booting a Linux kernel which requires 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. If you do not pass a third \n "
" \t a bd_info struct will be passed instead \n "
# endif
" " ;
# endif
U_BOOT_CMD (
bootz , CONFIG_SYS_MAXARGS , 1 , do_bootz ,
" 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 ) ;
unmap_sysmem ( ih ) ;
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 ) ) ;
unmap_sysmem ( ih ) ;
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
* have a header that provide this informaiton .
*/
if ( bootm_find_images ( 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 arm64 Linux Image stored in memory \n "
" \t The argument 'initrd' is optional and specifies the address \n "
" \t of an initrd in memory. The optional parameter ':size' allows \n "
" \t specifying the size of a RAW initrd. \n "
# if defined(CONFIG_OF_LIBFDT)
" \t Since booting a Linux kernel requires a flat device-tree, a \n "
" \t third argument providing the address of the device-tree blob \n "
" \t is required. To boot a kernel with a device-tree blob but \n "
" \t without an initrd image, use a '-' for the initrd 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 */