aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/i386/image
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2012-04-15 00:15:41 +0100
committerMichael Brown <mcb30@ipxe.org>2012-04-15 00:38:43 +0100
commitd11b82f0e401ca6499e590fa348c8dbd67bc1d40 (patch)
tree90fb07d90db7e70737add6992d25de8831df6f8e /src/arch/i386/image
parentcc288dc0f88e6b3aa578073ffb7566db50920f08 (diff)
downloadipxe-d11b82f0e401ca6499e590fa348c8dbd67bc1d40.tar.gz
[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>
Diffstat (limited to 'src/arch/i386/image')
-rw-r--r--src/arch/i386/image/multiboot.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/src/arch/i386/image/multiboot.c b/src/arch/i386/image/multiboot.c
index 15e8fd52..0336581f 100644
--- a/src/arch/i386/image/multiboot.c
+++ b/src/arch/i386/image/multiboot.c
@@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/elf.h>
#include <ipxe/init.h>
#include <ipxe/features.h>
+#include <ipxe/uri.h>
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
*
- * @v imgname Image name
- * @v cmdline Command line
+ * @v image Image
* @ret physaddr Physical address of command line
*/
-physaddr_t multiboot_add_cmdline ( const char *imgname, const char *cmdline ) {
- char *mb_cmdline;
-
- if ( ! cmdline )
- cmdline = "";
-
- /* Copy command line to base memory buffer */
- mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
- mb_cmdline_offset +=
- ( snprintf ( mb_cmdline,
- ( sizeof ( mb_cmdlines ) - mb_cmdline_offset ),
- "%s %s", imgname, cmdline ) + 1 );
-
- /* Truncate to terminating NUL in buffer if necessary */
- if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) )
- mb_cmdline_offset = ( sizeof ( mb_cmdlines ) - 1 );
+physaddr_t multiboot_add_cmdline ( struct image *image ) {
+ char *mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
+ size_t remaining = ( sizeof ( mb_cmdlines ) - mb_cmdline_offset );
+ char *buf = mb_cmdline;
+ size_t len;
+
+ /* Copy image URI to base memory buffer as start of command line */
+ 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, if present */
+ if ( image->cmdline ) {
+ mb_cmdline_offset--; /* Strip NUL */
+ buf--;
+ remaining++;
+ len = ( snprintf ( buf, remaining, " %s",
+ image->cmdline ) + 1 /* NUL */ );
+ if ( len > remaining )
+ len = remaining;
+ mb_cmdline_offset += len;
+ }
return virt_to_phys ( mb_cmdline );
}
@@ -209,8 +219,7 @@ 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->name,
- module_image->cmdline );
+ module->string = multiboot_add_cmdline ( module_image );
module->reserved = 0;
/* 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 |
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
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,
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
mbinfo.mods_addr = virt_to_phys ( mbmodules );