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