* Copyright 2003-2013, Axel DΓΆrfler, axeld@pinc-software.de.
* 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/PathBlocklist.h>
#include <boot/stdio.h>
#include <system_revision.h>
#include "file_systems/packagefs/packagefs.h"
#ifdef TRACE_MAIN
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
void *__dso_handle;
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"));
#if KDEBUG_ENABLE_DEBUG_SYSLOG
gKernelArgs.keep_debug_output_buffer = true;
gKernelArgs.previous_debug_size = true;
#endif
add_stage2_driver_settings(args);
platform_init_video();
if (vfs_init(args) < B_OK)
panic("Could not initialize VFS!\n");
dprintf("Welcome to the Haiku boot loader!\n");
dprintf("Haiku revision: %s\n", get_haiku_revision());
bool mountedAllVolumes = false;
BootVolume bootVolume;
PathBlocklist pathBlocklist;
if (get_boot_file_system(args, bootVolume) != B_OK
|| (platform_boot_options() & BOOT_OPTION_MENU) != 0) {
if (!bootVolume.IsValid())
puts("\tno boot path found, scan for all partitions...\n");
if (mount_file_systems(args) < B_OK) {
puts("Could not locate any supported boot devices!\n");
}
mountedAllVolumes = true;
if (user_menu(bootVolume, pathBlocklist) < B_OK) {
goto out;
}
}
if (bootVolume.IsValid()) {
#ifndef __riscv
load_driver_settings(args, bootVolume.RootDirectory());
#endif
status_t status;
while ((status = load_kernel(args, bootVolume)) < B_OK) {
bootVolume.Unset();
if (!mountedAllVolumes) {
if (mount_file_systems(args) < B_OK)
panic("Could not locate any supported boot devices!\n");
mountedAllVolumes = true;
}
if (user_menu(bootVolume, pathBlocklist) != B_OK
|| !bootVolume.IsValid()) {
goto out;
}
}
if (status == B_OK) {
if (bootVolume.IsPackaged()) {
packagefs_apply_path_blocklist(bootVolume.SystemDirectory(),
pathBlocklist);
}
register_boot_file_system(bootVolume);
if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0)
platform_switch_to_logo();
load_modules(args, bootVolume);
gKernelArgs.ucode_data = NULL;
gKernelArgs.ucode_data_size = 0;
platform_load_ucode(bootVolume);
#ifndef __riscv
apply_boot_settings();
#endif
gKernelArgs.kernel_args_size = sizeof(kernel_args);
gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION;
if (gKernelArgs.ucode_data == NULL)
gKernelArgs.kernel_args_size = kernel_args_size_v1;
void* buffer = kernel_args_malloc(gBootParams.ContentSize() + 7);
if (!buffer) {
panic("Could not allocate memory for the boot volume kernel "
"arguments");
}
buffer = (void*)(((addr_t)buffer + 7) & ~(addr_t)0x7);
memcpy(buffer, gBootParams.Buffer(), gBootParams.ContentSize());
gKernelArgs.boot_volume = buffer;
gKernelArgs.boot_volume_size = gBootParams.ContentSize();
platform_cleanup_devices();
platform_start_kernel();
}
}
out:
heap_release();
return 0;
}