Testing a Multiboot specification compatible kernel entrypoint I found that qemu -kernel foo -append bar results in the Multiboot command line being passed as "foo bar". Just -kernel foo results in "foo " (with trailing blank). If the filename given to -kernel contains a blank, like -kernel "quux foo" with -append bar then the command line contains that blank, unquoted, like "quux foo bar".
GRUB2 only passes the command line content in the Multiboot command line. For example, given the kernel command "multiboot /foo bar" GRUB2 only passes "bar" in the Multiboot command line. I consider GRUB2 to be the authoritative example implementation as far as the Multiboot specification is concerned. Test case is as follows, using ldosboot [1], lmacros [2], scanptab [3], and bootimg [4]: ldosboot$ nasm -I ../lmacros/ testpl.asm -o testpl.bin -l testpl.lst && nasm -I ../lmacros/ -I ./ -I ../scanptab/ -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK -D_IMAGE_EXE_MIN_CALC=_IMAGE_EXE_AUTO_STACK -D_IMAGE_EXE_MAX=0 -D_PAYLOAD_FILE='"testpl.bin"' -D_INILOAD_SIGNATURE='"TP"' iniload.asm -o testpl.com -l testpli.lst && nasm ../bootimg/bootimg.asm -D_MBR -o diskq.img -D_UNIT=80h -D_PAYLOADFILE=::empty -I ../lmacros/ -l diskq.lst && timeout --foreground 10 qemu-system-i386 -kernel testpl.com -curses -hda diskq.img -append baz 2> /dev/null; stty sane (The -hda disk image is needed because my kernel's iniload stage expects to be booted off a valid FAT filesystem partition, and also qemu -kernel passes ROM-BIOS unit 80h (first harddisk unit) partition 0 (first primary partition) to the Multiboot specification entrypoint, even if no hard disk is present at all.) Relevant output line on broken qemu: > Kernel command line = "testpl.com baz" Expected output: (as seen when booted from GRUB2, or patched qemu) > Kernel command line = "baz" Signed-off-by: C. Masloch <pus...@ulukai.org> [1]: https://hg.ulukai.org/ecm/ldosboot [2]: https://hg.ulukai.org/ecm/lmacros [3]: https://hg.ulukai.org/ecm/scanptab [4]: https://hg.ulukai.org/ecm/bootimg diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 9e7d69d470..78b36902ff 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -288,8 +288,7 @@ int load_multiboot(FWCfgState *fw_cfg, mbs.offset_mbinfo = mbs.mb_buf_size; /* Calculate space for cmdlines, bootloader name, and mb_mods */ - cmdline_len = strlen(kernel_filename) + 1; - cmdline_len += strlen(kernel_cmdline) + 1; + cmdline_len = strlen(kernel_cmdline) + 1; if (initrd_filename) { const char *r = initrd_filename; cmdline_len += strlen(initrd_filename) + 1; @@ -360,10 +359,7 @@ int load_multiboot(FWCfgState *fw_cfg, } /* Commandline support */ - char kcmdline[strlen(kernel_filename) + strlen(kernel_cmdline) + 2]; - snprintf(kcmdline, sizeof(kcmdline), "%s %s", - kernel_filename, kernel_cmdline); - stl_p(bootinfo + MBI_CMDLINE, mb_add_cmdline(&mbs, kcmdline)); + stl_p(bootinfo + MBI_CMDLINE, mb_add_cmdline(&mbs, kernel_cmdline)); stl_p(bootinfo + MBI_BOOTLOADER, mb_add_bootloader(&mbs, bootloader_name));