1 /* 2 * Copyright 2008, Rene Gollent, rene@gollent.com. All rights reserved. 3 * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "load_driver_settings.h" 9 10 #include <string.h> 11 #include <unistd.h> 12 13 #include <OS.h> 14 #include <drivers/driver_settings.h> 15 16 #include <safemode_defs.h> 17 18 #include <boot/driver_settings.h> 19 #include <boot/kernel_args.h> 20 #include <boot/stage2.h> 21 #include <boot/platform.h> 22 23 24 static status_t 25 load_driver_settings_file(Directory* directory, const char* name) 26 { 27 int fd = open_from(directory, name, O_RDONLY); 28 if (fd < 0) 29 return fd; 30 31 struct stat stat; 32 fstat(fd, &stat); 33 34 char* buffer = (char*)kernel_args_malloc(stat.st_size + 1); 35 if (buffer == NULL) 36 return B_NO_MEMORY; 37 38 if (read(fd, buffer, stat.st_size) != stat.st_size) 39 return B_IO_ERROR; 40 41 driver_settings_file* file = (driver_settings_file*)kernel_args_malloc( 42 sizeof(driver_settings_file)); 43 if (file == NULL) { 44 kernel_args_free(buffer); 45 return B_NO_MEMORY; 46 } 47 48 buffer[stat.st_size] = '\0'; 49 // null terminate the buffer 50 51 strlcpy(file->name, name, sizeof(file->name)); 52 file->buffer = buffer; 53 file->size = stat.st_size; 54 55 // add it to the list 56 file->next = gKernelArgs.driver_settings; 57 gKernelArgs.driver_settings = file; 58 59 return B_OK; 60 } 61 62 63 static void 64 apply_boot_settings(void* kernelSettings, void* safemodeSettings) 65 { 66 #if B_HAIKU_PHYSICAL_BITS > 32 67 if (get_driver_boolean_parameter(kernelSettings, "4gb_memory_limit", false, 68 false) 69 || get_driver_boolean_parameter(safemodeSettings, 70 B_SAFEMODE_4_GB_MEMORY_LIMIT, false, false)) { 71 ignore_physical_memory_ranges_beyond_4gb(); 72 } 73 #endif 74 } 75 76 77 // #pragma mark - 78 79 80 status_t 81 load_driver_settings(stage2_args* /*args*/, Directory* volume) 82 { 83 int fd = open_from(volume, "home/config/settings/kernel/drivers", O_RDONLY); 84 if (fd < B_OK) 85 return fd; 86 87 Directory* settings = (Directory*)get_node_from(fd); 88 if (settings == NULL) 89 return B_ENTRY_NOT_FOUND; 90 91 void* cookie; 92 if (settings->Open(&cookie, O_RDONLY) == B_OK) { 93 char name[B_FILE_NAME_LENGTH]; 94 while (settings->GetNextEntry(cookie, name, sizeof(name)) == B_OK) { 95 if (!strcmp(name, ".") || !strcmp(name, "..")) 96 continue; 97 98 status_t status = load_driver_settings_file(settings, name); 99 if (status != B_OK) 100 dprintf("Could not load \"%s\" error %ld\n", name, status); 101 } 102 103 settings->Close(cookie); 104 } 105 106 return B_OK; 107 } 108 109 110 status_t 111 add_stage2_driver_settings(stage2_args* args) 112 { 113 // TODO: split more intelligently 114 for (const char** arg = args->arguments; 115 arg != NULL && arg[0] != NULL; arg++) { 116 dprintf("adding args: '%s'\n", arg[0]); 117 add_safe_mode_settings((char*)arg[0]); 118 } 119 return B_OK; 120 } 121 122 123 status_t 124 add_safe_mode_settings(char* settings) 125 { 126 if (settings == NULL || settings[0] == '\0') 127 return B_OK; 128 129 size_t length = strlen(settings); 130 char* buffer = (char*)kernel_args_malloc(length + 1); 131 if (buffer == NULL) 132 return B_NO_MEMORY; 133 134 driver_settings_file* file = (driver_settings_file*)kernel_args_malloc( 135 sizeof(driver_settings_file)); 136 if (file == NULL) { 137 kernel_args_free(buffer); 138 return B_NO_MEMORY; 139 } 140 141 strlcpy(file->name, B_SAFEMODE_DRIVER_SETTINGS, sizeof(file->name)); 142 memcpy(buffer, settings, length + 1); 143 file->buffer = buffer; 144 file->size = length; 145 146 // add it to the list 147 file->next = gKernelArgs.driver_settings; 148 gKernelArgs.driver_settings = file; 149 150 return B_OK; 151 } 152 153 154 void 155 apply_boot_settings() 156 { 157 void* kernelSettings = load_driver_settings("kernel"); 158 void* safemodeSettings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); 159 160 apply_boot_settings(kernelSettings, safemodeSettings); 161 162 if (safemodeSettings != NULL) 163 unload_driver_settings(safemodeSettings); 164 if (kernelSettings) 165 unload_driver_settings(kernelSettings); 166 } 167