- 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
138 lines
3.4 KiB
C++
138 lines
3.4 KiB
C++
/*
|
|
* Copyright 2003-2005, Axel Dörfler, [email protected].
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include "menu.h"
|
|
#include "loader.h"
|
|
#include "load_driver_settings.h"
|
|
|
|
#include <boot/stage2.h>
|
|
#include <boot/vfs.h>
|
|
#include <boot/platform.h>
|
|
#include <boot/heap.h>
|
|
#include <boot/stdio.h>
|
|
|
|
#include <util/kernel_cpp.h>
|
|
|
|
|
|
//#define TRACE_MAIN
|
|
#ifdef TRACE_MAIN
|
|
# define TRACE(x) dprintf x
|
|
#else
|
|
# define TRACE(x) ;
|
|
#endif
|
|
|
|
|
|
extern "C" int
|
|
main(stage2_args *args)
|
|
{
|
|
TRACE(("boot(): enter\n"));
|
|
|
|
if (heap_init(args) < B_OK)
|
|
panic("Could not initialize heap!\n");
|
|
|
|
TRACE(("boot(): heap initialized...\n"));
|
|
|
|
// construct boot_volume KMessage explicitely
|
|
new(&gKernelArgs.boot_volume) KMessage;
|
|
|
|
add_stage2_driver_settings(args);
|
|
|
|
platform_init_video();
|
|
|
|
// the main platform dependent initialisation
|
|
// has already taken place at this point.
|
|
|
|
if (vfs_init(args) < B_OK)
|
|
panic("Could not initialize VFS!\n");
|
|
|
|
dprintf("Welcome to the Haiku boot loader!\n");
|
|
|
|
bool mountedAllVolumes = false;
|
|
|
|
Directory *volume = get_boot_file_system(args);
|
|
|
|
if (volume == NULL || (platform_boot_options() & BOOT_OPTION_MENU) != 0) {
|
|
if (volume == NULL)
|
|
puts("\tno boot path found, scan for all partitions...\n");
|
|
|
|
if (mount_file_systems(args) < B_OK) {
|
|
// That's unfortunate, but we still give the user the possibility
|
|
// to insert a CD-ROM or just rescan the available devices
|
|
puts("Could not locate any supported boot devices!\n");
|
|
}
|
|
|
|
// ToDo: check if there is only one bootable volume!
|
|
|
|
mountedAllVolumes = true;
|
|
|
|
if (user_menu(&volume) < B_OK) {
|
|
// user requested to quit the loader
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (volume != NULL) {
|
|
// we got a volume to boot from!
|
|
status_t status;
|
|
while ((status = load_kernel(args, volume)) < B_OK) {
|
|
// loading the kernel failed, so let the user choose another
|
|
// volume to boot from until it works
|
|
volume = NULL;
|
|
|
|
if (!mountedAllVolumes) {
|
|
// mount all other file systems, if not already happened
|
|
if (mount_file_systems(args) < B_OK)
|
|
panic("Could not locate any supported boot devices!\n");
|
|
|
|
mountedAllVolumes = true;
|
|
}
|
|
|
|
if (user_menu(&volume) < B_OK || volume == NULL) {
|
|
// user requested to quit the loader
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
// if everything is okay, continue booting; the kernel
|
|
// is already loaded at this point and we definitely
|
|
// know our boot volume, too
|
|
if (status == B_OK) {
|
|
register_boot_file_system(volume);
|
|
|
|
if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0)
|
|
platform_switch_to_logo();
|
|
|
|
load_modules(args, volume);
|
|
load_driver_settings(args, volume);
|
|
|
|
// set up kernel args version info
|
|
gKernelArgs.kernel_args_size = sizeof(kernel_args);
|
|
gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION;
|
|
|
|
// clone the boot_volume KMessage into kernel accessible memory
|
|
// note, that we need to 4 byte align the buffer and thus allocate
|
|
// 3 more bytes
|
|
KMessage& bootVolume = gKernelArgs.boot_volume;
|
|
void* buffer = kernel_args_malloc(bootVolume.ContentSize() + 3);
|
|
if (!buffer) {
|
|
panic("Could not allocate memory for the boot volume kernel "
|
|
"arguments");
|
|
}
|
|
|
|
buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3);
|
|
memcpy(buffer, bootVolume.Buffer(), bootVolume.ContentSize());
|
|
bootVolume.SetTo(buffer, bootVolume.ContentSize());
|
|
|
|
// ToDo: cleanup, heap_release() etc.
|
|
platform_start_kernel();
|
|
}
|
|
}
|
|
|
|
out:
|
|
heap_release(args);
|
|
return 0;
|
|
}
|