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