vfs: check userland buffers before reading them.
[haiku.git] / src / system / boot / loader / main.cpp
blobbb7a063ccc9cbe013348fb9e156f7ff61ec7feb0
1 /*
2 * Copyright 2003-2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "menu.h"
8 #include "loader.h"
9 #include "load_driver_settings.h"
11 #include <boot/stage2.h>
12 #include <boot/vfs.h>
13 #include <boot/platform.h>
14 #include <boot/heap.h>
15 #include <boot/PathBlacklist.h>
16 #include <boot/stdio.h>
18 #include "file_systems/packagefs/packagefs.h"
21 //#define TRACE_MAIN
22 #ifdef TRACE_MAIN
23 # define TRACE(x) dprintf x
24 #else
25 # define TRACE(x) ;
26 #endif
29 void *__dso_handle;
32 extern "C" int
33 main(stage2_args *args)
35 TRACE(("boot(): enter\n"));
37 if (heap_init(args) < B_OK)
38 panic("Could not initialize heap!\n");
40 TRACE(("boot(): heap initialized...\n"));
42 // set debug syslog default
43 #if KDEBUG_ENABLE_DEBUG_SYSLOG
44 gKernelArgs.keep_debug_output_buffer = true;
45 gKernelArgs.previous_debug_size = true;
46 // used as a boolean indicator until initialized for the kernel
47 #endif
49 add_stage2_driver_settings(args);
51 platform_init_video();
53 // the main platform dependent initialisation
54 // has already taken place at this point.
56 if (vfs_init(args) < B_OK)
57 panic("Could not initialize VFS!\n");
59 dprintf("Welcome to the Haiku boot loader!\n");
61 bool mountedAllVolumes = false;
63 BootVolume bootVolume;
64 PathBlacklist pathBlacklist;
66 if (get_boot_file_system(args, bootVolume) != B_OK
67 || (platform_boot_options() & BOOT_OPTION_MENU) != 0) {
68 if (!bootVolume.IsValid())
69 puts("\tno boot path found, scan for all partitions...\n");
71 if (mount_file_systems(args) < B_OK) {
72 // That's unfortunate, but we still give the user the possibility
73 // to insert a CD-ROM or just rescan the available devices
74 puts("Could not locate any supported boot devices!\n");
77 // ToDo: check if there is only one bootable volume!
79 mountedAllVolumes = true;
81 if (user_menu(bootVolume, pathBlacklist) < B_OK) {
82 // user requested to quit the loader
83 goto out;
87 if (bootVolume.IsValid()) {
88 // we got a volume to boot from!
89 status_t status;
90 while ((status = load_kernel(args, bootVolume)) < B_OK) {
91 // loading the kernel failed, so let the user choose another
92 // volume to boot from until it works
93 bootVolume.Unset();
95 if (!mountedAllVolumes) {
96 // mount all other file systems, if not already happened
97 if (mount_file_systems(args) < B_OK)
98 panic("Could not locate any supported boot devices!\n");
100 mountedAllVolumes = true;
103 if (user_menu(bootVolume, pathBlacklist) != B_OK
104 || !bootVolume.IsValid()) {
105 // user requested to quit the loader
106 goto out;
110 // if everything is okay, continue booting; the kernel
111 // is already loaded at this point and we definitely
112 // know our boot volume, too
113 if (status == B_OK) {
114 if (bootVolume.IsPackaged()) {
115 packagefs_apply_path_blacklist(bootVolume.SystemDirectory(),
116 pathBlacklist);
119 register_boot_file_system(bootVolume);
121 if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0)
122 platform_switch_to_logo();
124 load_modules(args, bootVolume);
125 load_driver_settings(args, bootVolume.RootDirectory());
127 // apply boot settings
128 apply_boot_settings();
130 // set up kernel args version info
131 gKernelArgs.kernel_args_size = sizeof(kernel_args);
132 gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION;
134 // clone the boot_volume KMessage into kernel accessible memory
135 // note, that we need to 4 byte align the buffer and thus allocate
136 // 3 more bytes
137 void* buffer = kernel_args_malloc(gBootVolume.ContentSize() + 3);
138 if (!buffer) {
139 panic("Could not allocate memory for the boot volume kernel "
140 "arguments");
143 buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3);
144 memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize());
145 gKernelArgs.boot_volume = buffer;
146 gKernelArgs.boot_volume_size = gBootVolume.ContentSize();
148 // ToDo: cleanup, heap_release() etc.
149 heap_print_statistics();
150 platform_start_kernel();
154 out:
155 heap_release(args);
156 return 0;