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/stdio.h> 16 17 18 //#define TRACE_MAIN 19 #ifdef TRACE_MAIN 20 # define TRACE(x) dprintf x 21 #else 22 # define TRACE(x) ; 23 #endif 24 25 26 extern "C" int 27 main(stage2_args *args) 28 { 29 TRACE(("boot(): enter\n")); 30 31 if (heap_init(args) < B_OK) 32 panic("Could not initialize heap!\n"); 33 34 TRACE(("boot(): heap initialized...\n")); 35 36 // set debug syslog default 37 #if KDEBUG_ENABLE_DEBUG_SYSLOG 38 gKernelArgs.keep_debug_output_buffer = true; 39 #endif 40 41 add_stage2_driver_settings(args); 42 43 platform_init_video(); 44 45 // the main platform dependent initialisation 46 // has already taken place at this point. 47 48 if (vfs_init(args) < B_OK) 49 panic("Could not initialize VFS!\n"); 50 51 dprintf("Welcome to the Haiku boot loader!\n"); 52 53 bool mountedAllVolumes = false; 54 55 BootVolume bootVolume; 56 57 if (get_boot_file_system(args, bootVolume) != B_OK 58 || (platform_boot_options() & BOOT_OPTION_MENU) != 0) { 59 if (!bootVolume.IsValid()) 60 puts("\tno boot path found, scan for all partitions...\n"); 61 62 if (mount_file_systems(args) < B_OK) { 63 // That's unfortunate, but we still give the user the possibility 64 // to insert a CD-ROM or just rescan the available devices 65 puts("Could not locate any supported boot devices!\n"); 66 } 67 68 // ToDo: check if there is only one bootable volume! 69 70 mountedAllVolumes = true; 71 72 if (user_menu(bootVolume) < B_OK) { 73 // user requested to quit the loader 74 goto out; 75 } 76 } 77 78 if (bootVolume.IsValid()) { 79 // we got a volume to boot from! 80 status_t status; 81 while ((status = load_kernel(args, bootVolume)) < B_OK) { 82 // loading the kernel failed, so let the user choose another 83 // volume to boot from until it works 84 bootVolume.Unset(); 85 86 if (!mountedAllVolumes) { 87 // mount all other file systems, if not already happened 88 if (mount_file_systems(args) < B_OK) 89 panic("Could not locate any supported boot devices!\n"); 90 91 mountedAllVolumes = true; 92 } 93 94 if (user_menu(bootVolume) < B_OK || !bootVolume.IsValid()) { 95 // user requested to quit the loader 96 goto out; 97 } 98 } 99 100 // if everything is okay, continue booting; the kernel 101 // is already loaded at this point and we definitely 102 // know our boot volume, too 103 if (status == B_OK) { 104 register_boot_file_system(bootVolume); 105 106 if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0) 107 platform_switch_to_logo(); 108 109 load_modules(args, bootVolume); 110 load_driver_settings(args, bootVolume.RootDirectory()); 111 112 // apply boot settings 113 apply_boot_settings(); 114 115 // set up kernel args version info 116 gKernelArgs.kernel_args_size = sizeof(kernel_args); 117 gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION; 118 119 // clone the boot_volume KMessage into kernel accessible memory 120 // note, that we need to 4 byte align the buffer and thus allocate 121 // 3 more bytes 122 void* buffer = kernel_args_malloc(gBootVolume.ContentSize() + 3); 123 if (!buffer) { 124 panic("Could not allocate memory for the boot volume kernel " 125 "arguments"); 126 } 127 128 buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3); 129 memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize()); 130 gKernelArgs.boot_volume = buffer; 131 gKernelArgs.boot_volume_size = gBootVolume.ContentSize(); 132 133 // ToDo: cleanup, heap_release() etc. 134 heap_print_statistics(); 135 platform_start_kernel(); 136 } 137 } 138 139 out: 140 heap_release(args); 141 return 0; 142 } 143