From 56c6c0fefbb82f729ae4dfd3ed04adfc236390cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 3 Aug 2009 14:39:41 +0000 Subject: [PATCH] - introduced an "argumetns" field in stage2_args to hold command line args from chaining loader, - added some multiboot support code: - dump some of the passed info, - parse command line (skip the 'kernel' name and pass the rest to stage2_args.arguments), - added an add_stage2_driver_settings() function which takes stage2_args.arguments and translates it into safe mode driver settings, a bit dumb for now. This allows using qemu -kernel haiku_loader -append 'debug_screen true' and get debug output without having to enter the menu (once multiboot info is used to determine the boot device too). The idea is to allow passing driver settings and using them to pass extra stuff (like 'force_keymap fr' and other stuff for demo), and to help automate tests ('run_test /bin/sometest'). This should answer Axel's question :) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32076 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/boot/stage2_args.h | 1 + .../boot/loader/load_driver_settings.cpp | 13 +++++ src/system/boot/loader/load_driver_settings.h | 1 + src/system/boot/loader/main.cpp | 2 + src/system/boot/platform/atari_m68k/start.c | 1 + src/system/boot/platform/bios_ia32/Jamfile | 1 + .../boot/platform/bios_ia32/multiboot.cpp | 51 +++++++++++++++++++ .../boot/platform/bios_ia32/multiboot.h | 19 ++++++- src/system/boot/platform/bios_ia32/start.c | 4 ++ src/system/boot/platform/openfirmware/start.c | 1 + 10 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/system/boot/platform/bios_ia32/multiboot.cpp diff --git a/headers/private/kernel/boot/stage2_args.h b/headers/private/kernel/boot/stage2_args.h index 7d6c3597e1..f4becc3c0b 100644 --- a/headers/private/kernel/boot/stage2_args.h +++ b/headers/private/kernel/boot/stage2_args.h @@ -12,6 +12,7 @@ typedef struct stage2_args { size_t heap_size; + const char **arguments; struct platform_stage2_args platform; } stage2_args ; diff --git a/src/system/boot/loader/load_driver_settings.cpp b/src/system/boot/loader/load_driver_settings.cpp index 1e5d80dfcf..c6f4d4d118 100644 --- a/src/system/boot/loader/load_driver_settings.cpp +++ b/src/system/boot/loader/load_driver_settings.cpp @@ -134,6 +134,19 @@ load_driver_settings(stage2_args */*args*/, Directory *volume) } +status_t +add_stage2_driver_settings(stage2_args *args) +{ + const char **p = args->arguments; + //TODO: split more intelligently + for (; p && *p; p++) { + dprintf("adding args: '%s'\n", *p); + add_safe_mode_settings((char *)*p); + } + return B_OK; +} + + status_t add_safe_mode_settings(char *settings) { diff --git a/src/system/boot/loader/load_driver_settings.h b/src/system/boot/loader/load_driver_settings.h index 499d79dc25..1648ab192f 100644 --- a/src/system/boot/loader/load_driver_settings.h +++ b/src/system/boot/loader/load_driver_settings.h @@ -10,6 +10,7 @@ extern status_t add_safe_mode_settings(char *buffer); +extern status_t add_stage2_driver_settings(stage2_args *args); extern status_t load_driver_settings(stage2_args *args, Directory *volume); #endif /* LOAD_DRIVER_SETTINGS_H */ diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index 76a5683b95..4d7b000067 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -38,6 +38,8 @@ main(stage2_args *args) // construct boot_volume KMessage explicitely new(&gKernelArgs.boot_volume) KMessage; + add_stage2_driver_settings(args); + platform_init_video(); // the main platform dependent initialisation diff --git a/src/system/boot/platform/atari_m68k/start.c b/src/system/boot/platform/atari_m68k/start.c index 394cc0a1b1..467a6e8093 100644 --- a/src/system/boot/platform/atari_m68k/start.c +++ b/src/system/boot/platform/atari_m68k/start.c @@ -132,6 +132,7 @@ _start(void) Bconout(DEV_CON, 'I'); args.heap_size = HEAP_SIZE; + args.arguments = NULL; // so we can dprintf init_nat_features(); diff --git a/src/system/boot/platform/bios_ia32/Jamfile b/src/system/boot/platform/bios_ia32/Jamfile index 889458ed8c..73f4f33a21 100644 --- a/src/system/boot/platform/bios_ia32/Jamfile +++ b/src/system/boot/platform/bios_ia32/Jamfile @@ -28,6 +28,7 @@ KernelMergeObject boot_platform_bios_ia32.o : keyboard.cpp menu.cpp mmu.cpp + multiboot.cpp cpu.cpp acpi.cpp smp.cpp diff --git a/src/system/boot/platform/bios_ia32/multiboot.cpp b/src/system/boot/platform/bios_ia32/multiboot.cpp new file mode 100644 index 0000000000..0eb241b762 --- /dev/null +++ b/src/system/boot/platform/bios_ia32/multiboot.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2009, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + */ + +#include "multiboot.h" + +#include +#include +#include + +extern struct multiboot_info *gMultiBootInfo; + +// load_driver_settings.h +extern status_t add_safe_mode_settings(char *buffer); + +void +dump_multiboot_info(void) +{ + if (!gMultiBootInfo) + return; + dprintf("Found MultiBoot Info at %p\n", gMultiBootInfo); + dprintf(" flags: 0x%lx\n", gMultiBootInfo->flags); + if (gMultiBootInfo->flags & MULTIBOOT_INFO_BOOTDEV) + dprintf(" boot_device: 0x%lx\n", gMultiBootInfo->boot_device); + if (gMultiBootInfo->flags & MULTIBOOT_INFO_CMDLINE && gMultiBootInfo->cmdline) + dprintf(" cmdline: '%s'\n", (char *)gMultiBootInfo->cmdline); + if (gMultiBootInfo->boot_loader_name) + dprintf(" boot_loader_name: '%s'\n", (char *)gMultiBootInfo->boot_loader_name); +} + + +status_t +parse_multiboot_commandline(stage2_args *args) +{ + static const char *sArgs[] = { NULL, NULL }; + if (!gMultiBootInfo || !(gMultiBootInfo->flags & MULTIBOOT_INFO_CMDLINE) || !gMultiBootInfo->cmdline) + return B_ENTRY_NOT_FOUND; + + const char *cmdline = (const char *)gMultiBootInfo->cmdline; + // skip kernel (bootloader) name + cmdline = strchr(cmdline, ' '); + if (!cmdline) + return B_ENTRY_NOT_FOUND; + cmdline++; + if (*cmdline == '\0') + return B_ENTRY_NOT_FOUND; + sArgs[0] = cmdline; + args->arguments = sArgs; + return B_OK; +} diff --git a/src/system/boot/platform/bios_ia32/multiboot.h b/src/system/boot/platform/bios_ia32/multiboot.h index 7280bd2189..5f22bcaad8 100644 --- a/src/system/boot/platform/bios_ia32/multiboot.h +++ b/src/system/boot/platform/bios_ia32/multiboot.h @@ -1,10 +1,14 @@ /* - * Copyright 2003-2006, François Revol, revol@free.fr. + * Copyright 2009, François Revol, revol@free.fr. * Distributed under the terms of the MIT License. */ #ifndef _MULTIBOOT_H #define _MULTIBOOT_H + +#include + + /* minimal part of the MultiBoot API */ /* magics */ @@ -49,4 +53,17 @@ struct multiboot_info { uint16 vbe_interface_len; }; + +#ifdef __cplusplus +extern "C" { +#endif + +extern void dump_multiboot_info(void); +extern status_t parse_multiboot_commandline(struct stage2_args *args); + +#ifdef __cplusplus +} +#endif + + #endif /* _MULTIBOOT_H */ diff --git a/src/system/boot/platform/bios_ia32/start.c b/src/system/boot/platform/bios_ia32/start.c index 105d4a4d74..947f138e62 100644 --- a/src/system/boot/platform/bios_ia32/start.c +++ b/src/system/boot/platform/bios_ia32/start.c @@ -13,6 +13,7 @@ #include "acpi.h" #include "keyboard.h" #include "bios.h" +#include "multiboot.h" #include #include @@ -120,11 +121,13 @@ _start(void) // call C++ constructors before doing anything else args.heap_size = HEAP_SIZE; + args.arguments = NULL; serial_init(); console_init(); cpu_init(); mmu_init(); + parse_multiboot_commandline(&args); // wait a bit to give the user the opportunity to press a key spin(750000); @@ -139,6 +142,7 @@ _start(void) acpi_init(); smp_init(); //hpet_init(); // TODO: Not yet + dump_multiboot_info(); main(&args); } diff --git a/src/system/boot/platform/openfirmware/start.c b/src/system/boot/platform/openfirmware/start.c index c2259f30d0..d4cf262c01 100644 --- a/src/system/boot/platform/openfirmware/start.c +++ b/src/system/boot/platform/openfirmware/start.c @@ -135,6 +135,7 @@ start(void *openFirmwareEntry) // stage2 args - might be set via the command line one day stage2_args args; args.heap_size = HEAP_SIZE; + args.arguments = NULL; of_init(openFirmwareEntry);