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