diff options
Diffstat (limited to 'gpxe/src/arch/i386/image/multiboot.c')
-rw-r--r-- | gpxe/src/arch/i386/image/multiboot.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/gpxe/src/arch/i386/image/multiboot.c b/gpxe/src/arch/i386/image/multiboot.c index 52bb10f6..5b620956 100644 --- a/gpxe/src/arch/i386/image/multiboot.c +++ b/gpxe/src/arch/i386/image/multiboot.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + /** * @file * @@ -139,10 +141,11 @@ static void multiboot_build_memmap ( struct image *image, /** * Add command line in base memory * + * @v imgname Image name * @v cmdline Command line * @ret physaddr Physical address of command line */ -physaddr_t multiboot_add_cmdline ( const char *cmdline ) { +physaddr_t multiboot_add_cmdline ( const char *imgname, const char *cmdline ) { char *mb_cmdline; if ( ! cmdline ) @@ -153,7 +156,7 @@ physaddr_t multiboot_add_cmdline ( const char *cmdline ) { mb_cmdline_offset += ( snprintf ( mb_cmdline, ( sizeof ( mb_cmdlines ) - mb_cmdline_offset ), - "%s", cmdline ) + 1 ); + "%s %s", imgname, cmdline ) + 1 ); /* Truncate to terminating NUL in buffer if necessary */ if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) ) @@ -208,8 +211,8 @@ multiboot_build_module_list ( struct image *image, ( ( count - insert ) * sizeof ( *module ) ) ); module->mod_start = start; module->mod_end = end; - module->string = - multiboot_add_cmdline ( module_image->cmdline ); + module->string = multiboot_add_cmdline ( module_image->name, + module_image->cmdline ); module->reserved = 0; /* We promise to page-align modules */ @@ -264,10 +267,8 @@ static int multiboot_exec ( struct image *image ) { memset ( &mbinfo, 0, sizeof ( mbinfo ) ); mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP | MBI_FLAG_CMDLINE | MBI_FLAG_MODS ); - multiboot_build_memmap ( image, &mbinfo, mbmemmap, - ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) ); mb_cmdline_offset = 0; - mbinfo.cmdline = multiboot_add_cmdline ( image->cmdline ); + mbinfo.cmdline = multiboot_add_cmdline ( image->name, image->cmdline ); mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules, ( sizeof(mbmodules) / sizeof(mbmodules[0]) ) ); mbinfo.mods_addr = virt_to_phys ( mbmodules ); @@ -279,6 +280,12 @@ static int multiboot_exec ( struct image *image ) { */ shutdown ( SHUTDOWN_BOOT ); + /* Build memory map after unhiding bootloader memory regions as part of + * shutting everything down. + */ + multiboot_build_memmap ( image, &mbinfo, mbmemmap, + ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) ); + /* Jump to OS with flat physical addressing */ DBGC ( image, "MULTIBOOT %p starting execution at %lx\n", image, entry ); @@ -360,6 +367,13 @@ static int multiboot_load_raw ( struct image *image, userptr_t buffer; int rc; + /* Sanity check */ + if ( ! ( hdr->mb.flags & MB_FLAG_RAW ) ) { + DBGC ( image, "MULTIBOOT %p is not flagged as a raw image\n", + image ); + return -EINVAL; + } + /* Verify and prepare segment */ offset = ( hdr->offset - hdr->mb.header_addr + hdr->mb.load_addr ); filesz = ( hdr->mb.load_end_addr ? @@ -432,14 +446,14 @@ static int multiboot_load ( struct image *image ) { return -ENOTSUP; } - /* Load the actual image */ - if ( hdr.mb.flags & MB_FLAG_RAW ) { - if ( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 ) - return rc; - } else { - if ( ( rc = multiboot_load_elf ( image ) ) != 0 ) - return rc; - } + /* There is technically a bit MB_FLAG_RAW to indicate whether + * this is an ELF or a raw image. In practice, grub will use + * the ELF header if present, and Solaris relies on this + * behaviour. + */ + if ( ( ( rc = multiboot_load_elf ( image ) ) != 0 ) && + ( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 ) ) + return rc; return 0; } |