xref: /haiku/src/system/boot/loader/load_driver_settings.cpp (revision 62b164bd7174bb8cbb4f1617c91cd13b3b2a5ccb)
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