1 /* 2 * Copyright 2003-2013, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "menu.h" 8 #include "loader.h" 9 #include "load_driver_settings.h" 10 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> 17 18 #include "file_systems/packagefs/packagefs.h" 19 20 21 //#define TRACE_MAIN 22 #ifdef TRACE_MAIN 23 # define TRACE(x) dprintf x 24 #else 25 # define TRACE(x) ; 26 #endif 27 28 29 void *__dso_handle; 30 31 32 extern "C" int 33 main(stage2_args *args) 34 { 35 TRACE(("boot(): enter\n")); 36 37 if (heap_init(args) < B_OK) 38 panic("Could not initialize heap!\n"); 39 40 TRACE(("boot(): heap initialized...\n")); 41 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 48 49 add_stage2_driver_settings(args); 50 51 platform_init_video(); 52 53 // the main platform dependent initialisation 54 // has already taken place at this point. 55 56 if (vfs_init(args) < B_OK) 57 panic("Could not initialize VFS!\n"); 58 59 dprintf("Welcome to the Haiku boot loader!\n"); 60 61 bool mountedAllVolumes = false; 62 63 BootVolume bootVolume; 64 PathBlacklist pathBlacklist; 65 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"); 70 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"); 75 } 76 77 // ToDo: check if there is only one bootable volume! 78 79 mountedAllVolumes = true; 80 81 if (user_menu(bootVolume, pathBlacklist) < B_OK) { 82 // user requested to quit the loader 83 goto out; 84 } 85 } 86 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(); 94 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"); 99 100 mountedAllVolumes = true; 101 } 102 103 if (user_menu(bootVolume, pathBlacklist) != B_OK 104 || !bootVolume.IsValid()) { 105 // user requested to quit the loader 106 goto out; 107 } 108 } 109 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); 117 } 118 119 register_boot_file_system(bootVolume); 120 121 if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0) 122 platform_switch_to_logo(); 123 124 load_modules(args, bootVolume); 125 load_driver_settings(args, bootVolume.RootDirectory()); 126 127 // apply boot settings 128 apply_boot_settings(); 129 130 // set up kernel args version info 131 gKernelArgs.kernel_args_size = sizeof(kernel_args); 132 gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION; 133 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"); 141 } 142 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(); 147 148 // ToDo: cleanup, heap_release() etc. 149 heap_print_statistics(); 150 platform_start_kernel(); 151 } 152 } 153 154 out: 155 heap_release(args); 156 return 0; 157 } 158