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