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