@ -52,6 +52,16 @@
# define COMMAND_LINE_SIZE 2048
# define COMMAND_LINE_SIZE 2048
unsigned generic_install_e820_map ( unsigned max_entries ,
struct e820entry * entries )
{
return 0 ;
}
unsigned install_e820_map ( unsigned max_entries ,
struct e820entry * entries )
__attribute__ ( ( weak , alias ( " generic_install_e820_map " ) ) ) ;
static void build_command_line ( char * command_line , int auto_boot )
static void build_command_line ( char * command_line , int auto_boot )
{
{
char * env_command_line ;
char * env_command_line ;
@ -81,13 +91,12 @@ static void build_command_line(char *command_line, int auto_boot)
void * load_zimage ( char * image , unsigned long kernel_size ,
void * load_zimage ( char * image , unsigned long kernel_size ,
unsigned long initrd_addr , unsigned long initrd_size ,
unsigned long initrd_addr , unsigned long initrd_size ,
int auto_boot )
int auto_boot , void * * load_address )
{
{
struct boot_params * setup_base ;
struct boot_params * setup_base ;
int setup_size ;
int setup_size ;
int bootproto ;
int bootproto ;
int big_image ;
int big_image ;
void * load_address ;
struct boot_params * params = ( struct boot_params * ) image ;
struct boot_params * params = ( struct boot_params * ) image ;
struct setup_header * hdr = & params - > hdr ;
struct setup_header * hdr = & params - > hdr ;
@ -134,14 +143,23 @@ void *load_zimage(char *image, unsigned long kernel_size,
/* Determine load address */
/* Determine load address */
if ( big_image )
if ( big_image )
load_address = ( void * ) BZIMAGE_LOAD_ADDR ;
* load_address = ( void * ) BZIMAGE_LOAD_ADDR ;
else
else
load_address = ( void * ) ZIMAGE_LOAD_ADDR ;
* load_address = ( void * ) ZIMAGE_LOAD_ADDR ;
# if defined CONFIG_ZBOOT_32
printf ( " Building boot_params at 0x%8.8lx \n " , ( ulong ) setup_base ) ;
memset ( setup_base , 0 , sizeof ( * setup_base ) ) ;
setup_base - > hdr = params - > hdr ;
setup_base - > e820_entries = install_e820_map (
ARRAY_SIZE ( setup_base - > e820_map ) , setup_base - > e820_map ) ;
# else
/* load setup */
/* load setup */
printf ( " Moving Real-Mode Code to 0x%8.8lx (%d bytes) \n " ,
printf ( " Moving Real-Mode Code to 0x%8.8lx (%d bytes) \n " ,
( ulong ) setup_base , setup_size ) ;
( ulong ) setup_base , setup_size ) ;
memmove ( setup_base , image , setup_size ) ;
memmove ( setup_base , image , setup_size ) ;
# endif
printf ( " Using boot protocol version %x.%02x \n " ,
printf ( " Using boot protocol version %x.%02x \n " ,
( bootproto & 0xff00 ) > > 8 , bootproto & 0xff ) ;
( bootproto & 0xff00 ) > > 8 , bootproto & 0xff ) ;
@ -180,7 +198,7 @@ void *load_zimage(char *image, unsigned long kernel_size,
if ( hdr - > setup_sects > = 15 ) {
if ( hdr - > setup_sects > = 15 ) {
printf ( " Linux kernel version %s \n " ,
printf ( " Linux kernel version %s \n " ,
( char * ) setup_base +
( char * ) params +
hdr - > kernel_version + 0x200 ) ;
hdr - > kernel_version + 0x200 ) ;
} else {
} else {
printf ( " Setup Sectors < 15 - "
printf ( " Setup Sectors < 15 - "
@ -235,17 +253,36 @@ void *load_zimage(char *image, unsigned long kernel_size,
build_command_line ( ( char * ) setup_base + COMMAND_LINE_OFFSET , auto_boot ) ;
build_command_line ( ( char * ) setup_base + COMMAND_LINE_OFFSET , auto_boot ) ;
printf ( " Loading %czImage at address 0x%08x (%ld bytes) \n " ,
printf ( " Loading %czImage at address 0x%08x (%ld bytes) \n " ,
big_image ? ' b ' : ' ' , ( u32 ) load_address , kernel_size ) ;
big_image ? ' b ' : ' ' , ( u32 ) * load_address , kernel_size ) ;
memmove ( load_address , image + setup_size , kernel_size ) ;
memmove ( * load_address , image + setup_size , kernel_size ) ;
/* ready for booting */
/* ready for booting */
return setup_base ;
return setup_base ;
}
}
void boot_zimage ( void * setup_base )
void boot_zimage ( void * setup_base , void * load_address )
{
{
printf ( " \n Starting kernel ... \n \n " ) ;
# if defined CONFIG_ZBOOT_32
/*
* Set % ebx , % ebp , and % edi to 0 , % esi to point to the boot_params
* structure , and then jump to the kernel . We assume that % cs is
* 0x10 , 4 GB flat , and read / execute , and the data segments are 0x18 ,
* 4 GB flat , and read / write . U - boot is setting them up that way for
* itself in arch / i386 / cpu / cpu . c .
*/
__asm__ __volatile__ (
" movl $0, %%ebp \n "
" cli \n "
" jmp %[kernel_entry] \n "
: : [ kernel_entry ] " a " ( load_address ) ,
[ boot_params ] " S " ( setup_base ) ,
" b " ( 0 ) , " D " ( 0 )
: " %ebp "
) ;
# else
struct pt_regs regs ;
struct pt_regs regs ;
memset ( & regs , 0 , sizeof ( struct pt_regs ) ) ;
memset ( & regs , 0 , sizeof ( struct pt_regs ) ) ;
@ -256,12 +293,14 @@ void boot_zimage(void *setup_base)
regs . eflags = 0 ;
regs . eflags = 0 ;
enter_realmode ( ( ( u32 ) setup_base + SETUP_START_OFFSET ) > > 4 , 0 ,
enter_realmode ( ( ( u32 ) setup_base + SETUP_START_OFFSET ) > > 4 , 0 ,
& regs , & regs ) ;
& regs , & regs ) ;
# endif
}
}
int do_zboot ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
int do_zboot ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
{
void * base_ptr ;
void * base_ptr ;
void * bzImage_addr = NULL ;
void * bzImage_addr = NULL ;
void * load_address ;
char * s ;
char * s ;
ulong bzImage_size = 0 ;
ulong bzImage_size = 0 ;
@ -285,7 +324,8 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
bzImage_size = simple_strtoul ( argv [ 2 ] , NULL , 16 ) ;
bzImage_size = simple_strtoul ( argv [ 2 ] , NULL , 16 ) ;
/* Lets look for */
/* Lets look for */
base_ptr = load_zimage ( bzImage_addr , bzImage_size , 0 , 0 , 0 ) ;
base_ptr = load_zimage ( bzImage_addr , bzImage_size , 0 , 0 , 0 ,
& load_address ) ;
if ( ! base_ptr ) {
if ( ! base_ptr ) {
printf ( " ## Kernel loading failed ... \n " ) ;
printf ( " ## Kernel loading failed ... \n " ) ;
@ -295,9 +335,7 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
( u32 ) base_ptr ) ;
( u32 ) base_ptr ) ;
/* we assume that the kernel is in place */
/* we assume that the kernel is in place */
printf ( " \n Starting kernel ... \n \n " ) ;
boot_zimage ( base_ptr , load_address ) ;
boot_zimage ( base_ptr ) ;
/* does not return */
/* does not return */
}
}