1 | /*␊ |
2 | * Copyright (c) 2009 Evan Lojewski. All rights reserved.␊ |
3 | *␊ |
4 | */␊ |
5 | ␊ |
6 | #include <mach-o/fat.h>␊ |
7 | #include <libkern/OSByteOrder.h>␊ |
8 | #include <mach/machine.h>␊ |
9 | ␊ |
10 | #include "libsaio.h"␊ |
11 | ␊ |
12 | #include "sl.h"␊ |
13 | #include "boot.h"␊ |
14 | #include "bootstruct.h"␊ |
15 | #include "xml.h"␊ |
16 | #include "drivers.h"␊ |
17 | #include "modules.h"␊ |
18 | ␊ |
19 | int␉␉runNetbookInstaller = 0;␊ |
20 | ␊ |
21 | long NBI_LoadDrivers( char * dirSpec );␊ |
22 | void NBI_md0Ramdisk();␊ |
23 | void NBI_PreBoot_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6);␊ |
24 | //void NBI_loadBootGraphics(void);␊ |
25 | void NBI_md0Ramdisk_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6);␊ |
26 | ␊ |
27 | #ifdef NBP_SUPPORT␊ |
28 | extern long NetLoadDrivers(char *dirSpec);␊ |
29 | #endif␊ |
30 | extern long FileLoadDrivers(char *dirSpec, long plugin);␊ |
31 | ␊ |
32 | extern char gMacOSVersion;␊ |
33 | ␊ |
34 | ␊ |
35 | extern long LoadDriverMKext(char *fileSpec);␊ |
36 | extern long LoadDriverPList(char *dirSpec, char *name, long bundleType);␊ |
37 | ␊ |
38 | extern long MatchLibraries( void );␊ |
39 | #if UNUSED␊ |
40 | extern long MatchPersonalities( void );␊ |
41 | #endif␊ |
42 | extern long LoadMatchedModules( void );␊ |
43 | extern long InitDriverSupport(void);␊ |
44 | extern char * gExtensionsSpec;␊ |
45 | extern char * gDriverSpec;␊ |
46 | extern char * gFileSpec;␊ |
47 | extern char * gTempSpec;␊ |
48 | extern char * gFileName;␊ |
49 | ␊ |
50 | #define kEnableNBI␉␉␉"EnableNBIModule"␊ |
51 | ␊ |
52 | void NetbookInstaller_start()␊ |
53 | {␊ |
54 | ␉bool enable = true;␊ |
55 | ␉getBoolForKey(kEnableNBI, &enable, &bootInfo->bootConfig) ;␊ |
56 | ␉␊ |
57 | ␉if (enable) ␊ |
58 | ␉register_hook_callback("PreBoot", &NBI_PreBoot_hook);␉␉␊ |
59 | ␉␊ |
60 | }␊ |
61 | ␊ |
62 | void NBI_PreBoot_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)␊ |
63 | {␉␊ |
64 | ␉␊ |
65 | ␉bool dummyVal = 0;␊ |
66 | ␉config_file_t systemVersion;␊ |
67 | ␉␊ |
68 | ␉char valid = false;␊ |
69 | ␉const char *val;␊ |
70 | ␉int len;␊ |
71 | ␉const char* gPrevMacOSBuildVersion;␊ |
72 | ␉␊ |
73 | ␉␊ |
74 | ␉if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion))␊ |
75 | ␉{␊ |
76 | ␉␉valid = true;␊ |
77 | ␉}␊ |
78 | ␉else if (!loadConfigFile("System/Library/CoreServices/ServerVersion.plist", &systemVersion))␊ |
79 | ␉{␊ |
80 | ␉␉valid = true;␊ |
81 | ␉}␊ |
82 | ␉␊ |
83 | ␉if (valid)␊ |
84 | ␉{␊ |
85 | ␉␉if (getValueForKey("ProductBuildVersion", &val, &len, &systemVersion))␊ |
86 | ␉␉{␊ |
87 | ␉␉␉␊ |
88 | ␉␉␉if (!loadConfigFile("Extra/SystemVersion.LastPatched.plist", &systemVersion))␊ |
89 | ␉␉␉{␊ |
90 | ␉␉␉␉if(getValueForKey("ProductBuildVersion", &gPrevMacOSBuildVersion, &len, &systemVersion))␊ |
91 | ␉␉␉␉{␊ |
92 | ␉␉␉␉␉if(strlen(val) != strlen(gPrevMacOSBuildVersion) ||␊ |
93 | ␉␉␉␉␉ strcmp(val, gPrevMacOSBuildVersion) != 0␊ |
94 | ␉␉␉␉␉ )␊ |
95 | ␉␉␉␉␉{␊ |
96 | ␉␉␉␉␉␉runNetbookInstaller = 1;␊ |
97 | ␉␉␉␉␉}␊ |
98 | ␉␉␉␉␉else ␊ |
99 | ␉␉␉␉␉{␊ |
100 | ␉␉␉␉␉␉// Only allow restore from hibernation if the system hasn't changed, probably a bad idea though␊ |
101 | ␉␉␉␉␉␉//char* val="/private/var/vm/sleepimage";␊ |
102 | ␉␉␉␉␉␉␊ |
103 | ␉␉␉␉␉␉// Do this first to be sure that root volume is mounted␊ |
104 | ␉␉␉␉␉␉//ret = GetFileInfo(0, val, &flags, &sleeptime);␊ |
105 | ␉␉␉␉␉␉␊ |
106 | ␉␉␉␉␉␉//printf("System version has not changed\n");␊ |
107 | ␉␉␉␉␉␉//runNetbookInstaller = 0;␊ |
108 | ␉␉␉␉␉␉␊ |
109 | ␉␉␉␉␉}␊ |
110 | ␉␉␉␉␉␊ |
111 | ␉␉␉␉}␊ |
112 | ␉␉␉}␊ |
113 | ␉␉}␊ |
114 | ␉}␊ |
115 | ␉␊ |
116 | ␉␊ |
117 | ␉␊ |
118 | ␉␊ |
119 | ␉␊ |
120 | ␉if (!runNetbookInstaller && getBoolForKey("recovery", &dummyVal, &bootInfo->bootConfig) && dummyVal)␊ |
121 | ␉{␊ |
122 | ␉␉if(dummyVal) runNetbookInstaller = 2;␊ |
123 | ␉}␊ |
124 | ␉␊ |
125 | ␉if(runNetbookInstaller)␊ |
126 | ␉{␊ |
127 | ␉␉␊ |
128 | ␉␉replace_function("_LoadDrivers", &NBI_LoadDrivers);␊ |
129 | ␉␉␊ |
130 | ␉␉if(runNetbookInstaller == 1 )␊ |
131 | ␉␉{␊ |
132 | ␉␉␉if (execute_hook("isRamDiskRegistred", NULL, NULL, NULL, NULL, NULL, NULL) == EFI_SUCCESS)␊ |
133 | ␉␉␉{␊ |
134 | ␉␉␉␉replace_function("_md0Ramdisk", &NBI_md0Ramdisk);␊ |
135 | ␉␉␉} ␊ |
136 | ␉␉␉else␊ |
137 | ␉␉␉{␊ |
138 | ␉␉␉␉register_hook_callback("md0Ramdisk", NBI_md0Ramdisk_hook);␊ |
139 | ␉␉␉}␊ |
140 | ␊ |
141 | ␉␉}␊ |
142 | ␉␉␊ |
143 | ␉␉// Force arch=i386 + -v␊ |
144 | ␉␉archCpuType = CPU_TYPE_I386;␊ |
145 | ␉␉gVerboseMode = true;␊ |
146 | ␉}␊ |
147 | }␊ |
148 | ␊ |
149 | void NBI_md0Ramdisk_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)␊ |
150 | {␊ |
151 | ␉NBI_md0Ramdisk();␉␊ |
152 | }␊ |
153 | ␊ |
154 | typedef struct RAMDiskParam␊ |
155 | {␊ |
156 | ␉ppnum_t base;␊ |
157 | ␉unsigned int size;␊ |
158 | } RAMDiskParam;␊ |
159 | ␊ |
160 | void NBI_md0Ramdisk()␊ |
161 | {␊ |
162 | ␉RAMDiskParam ramdiskPtr;␊ |
163 | ␉char filename[512];␊ |
164 | ␉int fh = -1;␊ |
165 | ␉␊ |
166 | ␉// TODO: embed NBI.img in this file␊ |
167 | ␉// If runNetbookInstaller is true, then the system has changed states, patch it ␊ |
168 | ␉sprintf(filename, "%s", "Extra/NetbookInstaller.img");;␊ |
169 | ␉fh = open(filename);␊ |
170 | ␉␊ |
171 | ␉if (fh >= 0)␊ |
172 | ␉{␊ |
173 | ␉␉verbose("Enabling ramdisk %s\n", filename);␊ |
174 | ␉␉␊ |
175 | ␉␉ramdiskPtr.size = file_size(fh);␊ |
176 | ␉␉ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);␊ |
177 | ␉␉␊ |
178 | ␉␉if(ramdiskPtr.size && ramdiskPtr.base)␊ |
179 | ␉␉{␊ |
180 | ␉␉␉// Read new ramdisk image contents in kernel memory.␊ |
181 | ␉␉␉if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)␊ |
182 | ␉␉␉{␉␉␉␉␊ |
183 | #if UNUSED␊ |
184 | AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid); ␊ |
185 | #else␊ |
186 | AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size);␊ |
187 | #endif␊ |
188 | ␉␉␉␉Node* node = DT__FindNode("/chosen/memory-map", false);␊ |
189 | ␉␉␉␉if(node != NULL)␊ |
190 | ␉␉␉␉{␊ |
191 | ␉␉␉␉␉DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr);␉␉␊ |
192 | ␉␉␉␉}␊ |
193 | ␉␉␉␉else␊ |
194 | ␉␉␉␉{␊ |
195 | ␉␉␉␉␉verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);␊ |
196 | ␉␉␉␉}␊ |
197 | ␉␉␉}␊ |
198 | ␉␉␉else␊ |
199 | ␉␉␉{␊ |
200 | ␉␉␉␉verbose("Unable to read md0 image %s.\n", filename);␊ |
201 | ␉␉␉}␉␉␉␊ |
202 | ␉␉}␊ |
203 | ␉␉else␊ |
204 | ␉␉{␊ |
205 | ␉␉␉verbose("md0 image %s is empty.\n", filename);␊ |
206 | ␉␉}␊ |
207 | ␉␉␊ |
208 | ␉␉close(fh);␊ |
209 | ␉␉␊ |
210 | ␉}␊ |
211 | }␊ |
212 | ␊ |
213 | ␊ |
214 | long NBI_LoadDrivers( char * dirSpec )␊ |
215 | {␊ |
216 | ␉␊ |
217 | char dirSpecExtra[1024];␊ |
218 | ␉␊ |
219 | if ( InitDriverSupport() != 0 )␊ |
220 | return 0;␊ |
221 | ␊ |
222 | ␉int step = 0;␊ |
223 | ␉execute_hook("ramDiskLoadDrivers", &step, NULL, NULL, NULL, NULL, NULL);␊ |
224 | #ifdef NBP_SUPPORT␉␊ |
225 | if ( gBootFileType == kNetworkDeviceType )␊ |
226 | {␊ |
227 | if (NetLoadDrivers(dirSpec) != 0)␊ |
228 | ␉␉{␊ |
229 | error("Could not load drivers from the network\n");␊ |
230 | return -1;␊ |
231 | }␊ |
232 | }␊ |
233 | else␊ |
234 | #endif␊ |
235 | ␉␉if ( gBootFileType == kBlockDeviceType )␊ |
236 | ␉␉{␊ |
237 | ␉␉␉verbose("Loading Recovery Extensions\n");␊ |
238 | ␉␉␉strcpy(dirSpecExtra, "/Extra/RecoveryExtensions/");␊ |
239 | ␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
240 | ␉␉␉␊ |
241 | #ifdef BOOT_HELPER_SUPPORT␉␉␉␊ |
242 | ␉␉␉// TODO: fix this, the order does matter, and it's not correct now.␊ |
243 | ␉␉␉// Also try to load Extensions from boot helper partitions.␊ |
244 | ␉␉␉if (gBootVolume->flags & kBVFlagBooter)␊ |
245 | ␉␉␉{␊ |
246 | ␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");␊ |
247 | ␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
248 | ␉␉␉␉{␊ |
249 | ␉␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");␊ |
250 | ␉␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
251 | ␉␉␉␉␉{␊ |
252 | ␉␉␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");␊ |
253 | ␉␉␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
254 | ␉␉␉␉␉}␊ |
255 | ␉␉␉␉}␊ |
256 | ␉␉␉}␊ |
257 | #endif␊ |
258 | ␉␉␉␊ |
259 | ␉␉␉if (gMKextName[0] != '\0')␊ |
260 | ␉␉␉{␊ |
261 | ␉␉␉␉verbose("LoadDrivers: Loading from [%s]\n", gMKextName);␊ |
262 | ␉␉␉␉if ( LoadDriverMKext(gMKextName) != 0 )␊ |
263 | ␉␉␉␉{␊ |
264 | ␉␉␉␉␉error("Could not load %s\n", gMKextName);␊ |
265 | ␉␉␉␉␉return -1;␊ |
266 | ␉␉␉␉}␊ |
267 | ␉␉␉}␊ |
268 | ␉␉␉else␊ |
269 | ␉␉␉{␊ |
270 | ␉␉␉␉strcpy(gExtensionsSpec, dirSpec);␊ |
271 | ␉␉␉␉strcat(gExtensionsSpec, "System/Library/");␊ |
272 | ␉␉␉␉FileLoadDrivers(gExtensionsSpec, 0);␊ |
273 | ␉␉␉}␊ |
274 | ␉␉}␊ |
275 | ␉␉else␊ |
276 | ␉␉{␊ |
277 | ␉␉␉return 0;␊ |
278 | ␉␉}␊ |
279 | #if UNUSED␊ |
280 | MatchPersonalities();␊ |
281 | #endif␊ |
282 | MatchLibraries();␊ |
283 | ␉␊ |
284 | LoadMatchedModules();␊ |
285 | ␉␊ |
286 | return 0;␊ |
287 | }␊ |
288 | |