[multiboot] Include full image URI in command line

Solaris kernels seem to rely on having the full kernel path present in
the multiboot command line; if only the kernel name is present then
the boot fails with the error message

  krtld: failed to open 'unix'

Debugged-by: Michael Brown <mcb30@ipxe.org>
Debugged-by: Scott McWhirter <scottm@joyent.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/6/head
Michael Brown 2012-04-15 00:15:41 +01:00
parent cc288dc0f8
commit d11b82f0e4
1 changed files with 28 additions and 19 deletions

View File

@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/elf.h> #include <ipxe/elf.h>
#include <ipxe/init.h> #include <ipxe/init.h>
#include <ipxe/features.h> #include <ipxe/features.h>
#include <ipxe/uri.h>
FEATURE ( FEATURE_IMAGE, "MBOOT", DHCP_EB_FEATURE_MULTIBOOT, 1 ); FEATURE ( FEATURE_IMAGE, "MBOOT", DHCP_EB_FEATURE_MULTIBOOT, 1 );
@ -139,26 +140,35 @@ static void multiboot_build_memmap ( struct image *image,
/** /**
* Add command line in base memory * Add command line in base memory
* *
* @v imgname Image name * @v image Image
* @v cmdline Command line
* @ret physaddr Physical address of command line * @ret physaddr Physical address of command line
*/ */
physaddr_t multiboot_add_cmdline ( const char *imgname, const char *cmdline ) { physaddr_t multiboot_add_cmdline ( struct image *image ) {
char *mb_cmdline; char *mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
size_t remaining = ( sizeof ( mb_cmdlines ) - mb_cmdline_offset );
char *buf = mb_cmdline;
size_t len;
if ( ! cmdline ) /* Copy image URI to base memory buffer as start of command line */
cmdline = ""; len = ( unparse_uri ( buf, remaining, image->uri,
URI_ALL ) + 1 /* NUL */ );
if ( len > remaining )
len = remaining;
mb_cmdline_offset += len;
buf += len;
remaining -= len;
/* Copy command line to base memory buffer */ /* Copy command line to base memory buffer, if present */
mb_cmdline = ( mb_cmdlines + mb_cmdline_offset ); if ( image->cmdline ) {
mb_cmdline_offset += mb_cmdline_offset--; /* Strip NUL */
( snprintf ( mb_cmdline, buf--;
( sizeof ( mb_cmdlines ) - mb_cmdline_offset ), remaining++;
"%s %s", imgname, cmdline ) + 1 ); len = ( snprintf ( buf, remaining, " %s",
image->cmdline ) + 1 /* NUL */ );
/* Truncate to terminating NUL in buffer if necessary */ if ( len > remaining )
if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) ) len = remaining;
mb_cmdline_offset = ( sizeof ( mb_cmdlines ) - 1 ); mb_cmdline_offset += len;
}
return virt_to_phys ( mb_cmdline ); return virt_to_phys ( mb_cmdline );
} }
@ -209,8 +219,7 @@ multiboot_build_module_list ( struct image *image,
( ( count - insert ) * sizeof ( *module ) ) ); ( ( count - insert ) * sizeof ( *module ) ) );
module->mod_start = start; module->mod_start = start;
module->mod_end = end; module->mod_end = end;
module->string = multiboot_add_cmdline ( module_image->name, module->string = multiboot_add_cmdline ( module_image );
module_image->cmdline );
module->reserved = 0; module->reserved = 0;
/* We promise to page-align modules */ /* We promise to page-align modules */
@ -405,7 +414,7 @@ static int multiboot_exec ( struct image *image ) {
mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP | mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP |
MBI_FLAG_CMDLINE | MBI_FLAG_MODS ); MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
mb_cmdline_offset = 0; mb_cmdline_offset = 0;
mbinfo.cmdline = multiboot_add_cmdline ( image->name, image->cmdline ); mbinfo.cmdline = multiboot_add_cmdline ( image );
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules, mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) ); ( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
mbinfo.mods_addr = virt_to_phys ( mbmodules ); mbinfo.mods_addr = virt_to_phys ( mbmodules );