- 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
This commit is contained in:
François Revol 2009-08-03 14:39:41 +00:00
parent 0b1db200df
commit 56c6c0fefb
10 changed files with 93 additions and 1 deletions

View File

@ -12,6 +12,7 @@
typedef struct stage2_args {
size_t heap_size;
const char **arguments;
struct platform_stage2_args platform;
} stage2_args ;

View File

@ -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)
{

View File

@ -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 */

View File

@ -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

View File

@ -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();

View File

@ -28,6 +28,7 @@ KernelMergeObject boot_platform_bios_ia32.o :
keyboard.cpp
menu.cpp
mmu.cpp
multiboot.cpp
cpu.cpp
acpi.cpp
smp.cpp

View File

@ -0,0 +1,51 @@
/*
* Copyright 2009, François Revol, revol@free.fr.
* Distributed under the terms of the MIT License.
*/
#include "multiboot.h"
#include <KernelExport.h>
#include <string.h>
#include <boot/stage2_args.h>
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;
}

View File

@ -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 <SupportDefs.h>
/* 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 */

View File

@ -13,6 +13,7 @@
#include "acpi.h"
#include "keyboard.h"
#include "bios.h"
#include "multiboot.h"
#include <KernelExport.h>
#include <boot/platform.h>
@ -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);
}

View File

@ -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);