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 load_driver_settings(args, bootVolume.RootDirectory()); 90 91 status_t status; 92 while ((status = load_kernel(args, bootVolume)) < B_OK) { 93 // loading the kernel failed, so let the user choose another 94 // volume to boot from until it works 95 bootVolume.Unset(); 96 97 if (!mountedAllVolumes) { 98 // mount all other file systems, if not already happened 99 if (mount_file_systems(args) < B_OK) 100 panic("Could not locate any supported boot devices!\n"); 101 102 mountedAllVolumes = true; 103 } 104 105 if (user_menu(bootVolume, pathBlacklist) != B_OK 106 || !bootVolume.IsValid()) { 107 // user requested to quit the loader 108 goto out; 109 } 110 } 111 112 // if everything is okay, continue booting; the kernel 113 // is already loaded at this point and we definitely 114 // know our boot volume, too 115 if (status == B_OK) { 116 if (bootVolume.IsPackaged()) { 117 packagefs_apply_path_blacklist(bootVolume.SystemDirectory(), 118 pathBlacklist); 119 } 120 121 register_boot_file_system(bootVolume); 122 123 if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0) 124 platform_switch_to_logo(); 125 126 load_modules(args, bootVolume); 127 128 // apply boot settings 129 apply_boot_settings(); 130 131 // set up kernel args version info 132 gKernelArgs.kernel_args_size = sizeof(kernel_args); 133 gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION; 134 135 // clone the boot_volume KMessage into kernel accessible memory 136 // note, that we need to 8-byte align the buffer and thus allocate 137 // 7 more bytes 138 void* buffer = kernel_args_malloc(gBootVolume.ContentSize() + 7); 139 if (!buffer) { 140 panic("Could not allocate memory for the boot volume kernel " 141 "arguments"); 142 } 143 144 buffer = (void*)(((addr_t)buffer + 7) & ~(addr_t)0x7); 145 memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize()); 146 gKernelArgs.boot_volume = buffer; 147 gKernelArgs.boot_volume_size = gBootVolume.ContentSize(); 148 149 // ToDo: cleanup, heap_release() etc. 150 heap_print_statistics(); 151 platform_start_kernel(); 152 } 153 } 154 155 out: 156 heap_release(args); 157 return 0; 158 } 159