Root/
Source at commit 1146 created 12 years 10 months ago. By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing). | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
7 | * Reserved. This file contains Original Code and/or Modifications of␊ |
8 | * Original Code as defined in and that are subject to the Apple Public␊ |
9 | * Source License Version 2.0 (the 'License'). You may not use this file␊ |
10 | * except in compliance with the License. Please obtain a copy of the␊ |
11 | * License at http://www.apple.com/publicsource and read it before using␊ |
12 | * this file.␊ |
13 | * ␊ |
14 | * The Original Code and all software distributed under the License are␊ |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
19 | * License for the specific language governing rights and limitations␊ |
20 | * under the License.␊ |
21 | * ␊ |
22 | * @APPLE_LICENSE_HEADER_END@␊ |
23 | */␊ |
24 | /*␊ |
25 | * drivers.c - Driver Loading Functions.␊ |
26 | *␊ |
27 | * Copyright (c) 2000 Apple Computer, Inc.␊ |
28 | *␊ |
29 | * DRI: Josh de Cesare␊ |
30 | */␊ |
31 | ␊ |
32 | #include <mach-o/fat.h>␊ |
33 | #include <libkern/OSByteOrder.h>␊ |
34 | #include <mach/machine.h>␊ |
35 | ␊ |
36 | #include "sl.h"␊ |
37 | #include "boot.h"␊ |
38 | #include "bootstruct.h"␊ |
39 | #include "xml.h"␊ |
40 | #include "ramdisk.h"␊ |
41 | #include "drivers.h"␊ |
42 | #include "modules.h"␊ |
43 | ␊ |
44 | extern char gMacOSVersion;␊ |
45 | ␊ |
46 | #ifndef OPTION_ROM␊ |
47 | long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);␊ |
48 | #endif␊ |
49 | ␊ |
50 | unsigned long Adler32( unsigned char * buffer, long length );␊ |
51 | ␊ |
52 | long FileLoadDrivers(char *dirSpec, long plugin);␊ |
53 | #ifndef OPTION_ROM␊ |
54 | long NetLoadDrivers(char *dirSpec);␊ |
55 | #endif␊ |
56 | long LoadDriverMKext(char *fileSpec);␊ |
57 | long LoadDriverPList(char *dirSpec, char *name, long bundleType);␊ |
58 | long LoadMatchedModules(void);␊ |
59 | long MatchPersonalities(void);␊ |
60 | long MatchLibraries(void);␊ |
61 | #ifdef NOTDEF␊ |
62 | static ModulePtr FindModule(char *name);␊ |
63 | static void ThinFatFile(void **loadAddrP, unsigned long *lengthP);␊ |
64 | #endif␊ |
65 | static long ParseXML(char *buffer, ModulePtr *module, TagPtr *personalities);␊ |
66 | long InitDriverSupport(void);␊ |
67 | ␊ |
68 | static ModulePtr gModuleHead, gModuleTail;␊ |
69 | static TagPtr gPersonalityHead, gPersonalityTail;␊ |
70 | char * gExtensionsSpec;␊ |
71 | char * gDriverSpec;␊ |
72 | char * gFileSpec;␊ |
73 | char * gTempSpec;␊ |
74 | char * gFileName;␊ |
75 | ␊ |
76 | unsigned long␊ |
77 | Adler32( unsigned char * buffer, long length )␊ |
78 | {␊ |
79 | long cnt;␊ |
80 | unsigned long result, lowHalf, highHalf;␊ |
81 | ␊ |
82 | lowHalf = 1;␊ |
83 | highHalf = 0;␊ |
84 | ␉␊ |
85 | ␉for ( cnt = 0; cnt < length; cnt++ )␊ |
86 | {␊ |
87 | if ((cnt % 5000) == 0)␊ |
88 | {␊ |
89 | lowHalf %= 65521L;␊ |
90 | highHalf %= 65521L;␊ |
91 | }␊ |
92 | ␉␉␊ |
93 | lowHalf += buffer[cnt];␊ |
94 | highHalf += lowHalf;␊ |
95 | }␊ |
96 | ␉␊ |
97 | ␉lowHalf %= 65521L;␊ |
98 | ␉highHalf %= 65521L;␊ |
99 | ␉␊ |
100 | ␉result = (highHalf << 16) | lowHalf;␊ |
101 | ␉␊ |
102 | return result;␊ |
103 | }␊ |
104 | ␊ |
105 | ␊ |
106 | //==========================================================================␊ |
107 | // InitDriverSupport␊ |
108 | ␊ |
109 | long␊ |
110 | InitDriverSupport( void )␊ |
111 | {␊ |
112 | gExtensionsSpec = malloc( 4096 );␊ |
113 | gDriverSpec = malloc( 4096 );␊ |
114 | gFileSpec = malloc( 4096 );␊ |
115 | gTempSpec = malloc( 4096 );␊ |
116 | gFileName = malloc( 4096 );␊ |
117 | ␉␊ |
118 | if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )␊ |
119 | stop("InitDriverSupport error");␊ |
120 | ␉␊ |
121 | return 0;␊ |
122 | }␊ |
123 | ␊ |
124 | //==========================================================================␊ |
125 | // LoadDrivers␊ |
126 | ␊ |
127 | long LoadDrivers( char * dirSpec )␊ |
128 | {␉␊ |
129 | char dirSpecExtra[1024];␊ |
130 | ␉␊ |
131 | if ( InitDriverSupport() != 0 )␊ |
132 | return 0;␊ |
133 | ␉␊ |
134 | #ifndef OPTION_ROM␊ |
135 | // Load extra drivers if a hook has been installed.␊ |
136 | if (LoadExtraDrivers_p != NULL)␊ |
137 | {␊ |
138 | (*LoadExtraDrivers_p)(&FileLoadDrivers);␊ |
139 | }␊ |
140 | ␉␊ |
141 | if ( gBootFileType == kNetworkDeviceType )␊ |
142 | {␊ |
143 | if (NetLoadDrivers(dirSpec) != 0) {␊ |
144 | error("Could not load drivers from the network\n");␊ |
145 | return -1;␊ |
146 | }␊ |
147 | }␊ |
148 | else␊ |
149 | #endif␊ |
150 | ␉␉if ( gBootFileType == kBlockDeviceType )␊ |
151 | ␉␉{␊ |
152 | ␉␉␉// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).␊ |
153 | #ifndef OPTION_ROM␊ |
154 | ␉␉␉// First try a specfic OS version folder ie 10.5␊ |
155 | ␉␉␉sprintf(dirSpecExtra, "rd(0,0)/Extra/%s/", &gMacOSVersion);␊ |
156 | ␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
157 | ␉␉␉{␉␊ |
158 | ␉␉␉␉// Next we'll try the base␊ |
159 | ␉␉␉␉strcpy(dirSpecExtra, "rd(0,0)/Extra/");␊ |
160 | ␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
161 | ␉␉␉}␊ |
162 | #endif␊ |
163 | ␉␉␉␊ |
164 | ␉␉␉// First try a specfic OS version folder ie 10.5␊ |
165 | ␉␉␉sprintf(dirSpecExtra, "/Extra/%s/", &gMacOSVersion);␊ |
166 | ␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
167 | ␉␉␉{␉␊ |
168 | ␉␉␉␉// Next try to load Extra extensions from the selected root partition.␊ |
169 | ␉␉␉␉strcpy(dirSpecExtra, "/Extra/");␊ |
170 | ␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
171 | ␉␉␉␉{␊ |
172 | ␉␉␉␉␉// If failed, then try to load Extra extensions from the boot partition␊ |
173 | ␉␉␉␉␉// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.␊ |
174 | ␉␉␉␉␉if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)␊ |
175 | #ifndef OPTION_ROM␊ |
176 | ␉␉␉␉␉␉|| (gRAMDiskVolume && gRAMDiskBTAliased) )␊ |
177 | #else␊ |
178 | ␉␉␉␉␉␉)␊ |
179 | #endif␊ |
180 | ␉␉␉␉␉{␊ |
181 | ␉␉␉␉␉␉// First try a specfic OS version folder ie 10.5␊ |
182 | ␉␉␉␉␉␉sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);␊ |
183 | ␉␉␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
184 | ␉␉␉␉␉␉{␉␊ |
185 | ␉␉␉␉␉␉␉// Next we'll try the base␊ |
186 | ␉␉␉␉␉␉␉strcpy(dirSpecExtra, "bt(0,0)/Extra/");␊ |
187 | ␉␉␉␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
188 | ␉␉␉␉␉␉}␊ |
189 | ␉␉␉␉␉}␊ |
190 | ␉␉␉␉}␊ |
191 | ␉␉␉␉␊ |
192 | ␉␉␉}␉␉␉␊ |
193 | ␉␉␉// TODO: fix this, the order does matter, and it's not correct now.␊ |
194 | ␉␉␉// Also try to load Extensions from boot helper partitions.␊ |
195 | ␉␉␉if (gBootVolume->flags & kBVFlagBooter)␊ |
196 | ␉␉␉{␊ |
197 | ␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");␊ |
198 | ␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
199 | ␉␉␉␉{␊ |
200 | ␉␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");␊ |
201 | ␉␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
202 | ␉␉␉␉␉{␊ |
203 | ␉␉␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");␊ |
204 | ␉␉␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
205 | ␉␉␉␉␉}␊ |
206 | ␉␉␉␉}␊ |
207 | ␉␉␉}␊ |
208 | ␉␉␉␊ |
209 | ␉␉␉if (gMKextName[0] != '\0')␊ |
210 | ␉␉␉{␊ |
211 | ␉␉␉␉verbose("LoadDrivers: Loading from [%s]\n", gMKextName);␊ |
212 | ␉␉␉␉if ( LoadDriverMKext(gMKextName) != 0 )␊ |
213 | ␉␉␉␉{␊ |
214 | ␉␉␉␉␉error("Could not load %s\n", gMKextName);␊ |
215 | ␉␉␉␉␉return -1;␊ |
216 | ␉␉␉␉}␊ |
217 | ␉␉␉}␊ |
218 | ␉␉␉else␊ |
219 | ␉␉␉{␊ |
220 | ␉␉␉␉strcpy(gExtensionsSpec, dirSpec);␊ |
221 | ␉␉␉␉strcat(gExtensionsSpec, "System/Library/");␊ |
222 | ␉␉␉␉FileLoadDrivers(gExtensionsSpec, 0);␊ |
223 | ␉␉␉}␊ |
224 | ␉␉}␊ |
225 | ␉␉else␊ |
226 | ␉␉{␊ |
227 | ␉␉␉return 0;␊ |
228 | ␉␉}␊ |
229 | ␉␊ |
230 | MatchPersonalities();␊ |
231 | ␉␊ |
232 | MatchLibraries();␊ |
233 | ␉␊ |
234 | LoadMatchedModules();␊ |
235 | ␉␊ |
236 | return 0;␊ |
237 | }␊ |
238 | ␊ |
239 | //==========================================================================␊ |
240 | // FileLoadMKext␊ |
241 | ␊ |
242 | static long␊ |
243 | FileLoadMKext( const char * dirSpec, const char * extDirSpec )␊ |
244 | {␊ |
245 | ␉long ret, flags, time, time2;␊ |
246 | ␉char altDirSpec[512];␊ |
247 | ␉␊ |
248 | ␉sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec);␊ |
249 | ␉ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);␊ |
250 | ␉if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))␊ |
251 | ␉{␊ |
252 | ␉␉ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);␊ |
253 | ␉␉if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||␊ |
254 | ␉␉␉(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))␊ |
255 | ␉␉{␊ |
256 | ␉␉␉sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);␊ |
257 | ␉␉␉verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
258 | ␉␉␉if (LoadDriverMKext(gDriverSpec) == 0) return 0;␊ |
259 | ␉␉}␊ |
260 | ␉}␊ |
261 | ␉return -1;␊ |
262 | }␊ |
263 | ␊ |
264 | //==========================================================================␊ |
265 | // FileLoadDrivers␊ |
266 | ␊ |
267 | long␊ |
268 | FileLoadDrivers( char * dirSpec, long plugin )␊ |
269 | {␊ |
270 | long ret, length, flags, time, bundleType;␊ |
271 | long long␉ index;␊ |
272 | long result = -1;␊ |
273 | const char * name;␊ |
274 | ␉␊ |
275 | if ( !plugin )␊ |
276 | {␊ |
277 | // First try 10.6's path for loading Extensions.mkext.␊ |
278 | if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0)␊ |
279 | ␉␉␉return 0;␊ |
280 | ␉␉␊ |
281 | // Next try the legacy path.␊ |
282 | else if (FileLoadMKext(dirSpec, "") == 0)␊ |
283 | ␉␉␉return 0;␊ |
284 | ␉␉␊ |
285 | strcat(dirSpec, "Extensions");␊ |
286 | }␊ |
287 | ␉␊ |
288 | index = 0;␊ |
289 | while (1) {␊ |
290 | ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);␊ |
291 | if (ret == -1) break;␊ |
292 | ␉␉␊ |
293 | // Make sure this is a directory.␊ |
294 | if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;␊ |
295 | ␊ |
296 | // Make sure this is a kext.␊ |
297 | length = strlen(name);␊ |
298 | if (strcmp(name + length - 5, ".kext")) continue;␊ |
299 | ␉␉␊ |
300 | // Save the file name.␊ |
301 | strcpy(gFileName, name);␊ |
302 | ␉␉␊ |
303 | // Determine the bundle type.␊ |
304 | sprintf(gTempSpec, "%s/%s", dirSpec, gFileName);␊ |
305 | ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);␊ |
306 | if (ret == 0) bundleType = kCFBundleType2;␊ |
307 | else bundleType = kCFBundleType3;␊ |
308 | ␉␉␊ |
309 | if (!plugin)␊ |
310 | sprintf(gDriverSpec, "%s/%s/%sPlugIns", dirSpec, gFileName,␊ |
311 | (bundleType == kCFBundleType2) ? "Contents/" : "");␊ |
312 | ␉␉␊ |
313 | ret = LoadDriverPList(dirSpec, gFileName, bundleType);␊ |
314 | ␉␉␊ |
315 | if (result != 0)␊ |
316 | ␉␉␉result = ret;␊ |
317 | ␉␉␊ |
318 | if (!plugin) ␊ |
319 | ␉␉␉FileLoadDrivers(gDriverSpec, 1);␊ |
320 | }␊ |
321 | ␉␊ |
322 | return result;␊ |
323 | }␊ |
324 | ␊ |
325 | //==========================================================================␊ |
326 | // ␊ |
327 | #ifndef OPTION_ROM␊ |
328 | long␊ |
329 | NetLoadDrivers( char * dirSpec )␊ |
330 | {␊ |
331 | long tries;␊ |
332 | ␉␊ |
333 | #if NODEF␊ |
334 | long cnt;␊ |
335 | ␉␊ |
336 | // Get the name of the kernel␊ |
337 | cnt = strlen(gBootFile);␊ |
338 | while (cnt--) {␊ |
339 | if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {␊ |
340 | ␉␉␉cnt++;␊ |
341 | ␉␉␉break;␊ |
342 | }␊ |
343 | }␊ |
344 | #endif␊ |
345 | ␉␊ |
346 | // INTEL modification␊ |
347 | sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootInfo->bootFile);␊ |
348 | ␊ |
349 | verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
350 | ␊ |
351 | tries = 3;␊ |
352 | while (tries--)␊ |
353 | {␊ |
354 | if (LoadDriverMKext(gDriverSpec) == 0) break;␊ |
355 | }␊ |
356 | if (tries == -1) return -1;␊ |
357 | ␉␊ |
358 | return 0;␊ |
359 | }␊ |
360 | #endif␊ |
361 | //==========================================================================␊ |
362 | // loadDriverMKext␊ |
363 | ␊ |
364 | long␊ |
365 | LoadDriverMKext( char * fileSpec )␊ |
366 | {␊ |
367 | unsigned long driversAddr, driversLength;␊ |
368 | long length;␊ |
369 | char segName[32];␊ |
370 | DriversPackage * package;␊ |
371 | ␉␊ |
372 | #define GetPackageElement(e) OSSwapBigToHostInt32(package->e)␊ |
373 | ␉␊ |
374 | // Load the MKext.␊ |
375 | length = LoadThinFatFile(fileSpec, (void **)&package);␊ |
376 | if (length < sizeof (DriversPackage)) return -1;␊ |
377 | ␉␊ |
378 | ␉// call hook to notify modules that the mkext has been loaded␊ |
379 | ␉execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);␊ |
380 | ␉␊ |
381 | ␉␊ |
382 | // Verify the MKext.␊ |
383 | if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||␊ |
384 | ( GetPackageElement(signature2) != kDriverPackageSignature2) ||␊ |
385 | ( GetPackageElement(length) > kLoadSize ) ||␊ |
386 | ( GetPackageElement(adler32) !=␊ |
387 | ␉␉ Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )␊ |
388 | {␊ |
389 | return -1;␊ |
390 | }␊ |
391 | ␉␊ |
392 | // Make space for the MKext.␊ |
393 | driversLength = GetPackageElement(length);␊ |
394 | driversAddr = AllocateKernelMemory(driversLength);␊ |
395 | ␉␊ |
396 | // Copy the MKext.␊ |
397 | memcpy((void *)driversAddr, (void *)package, driversLength);␊ |
398 | ␉␊ |
399 | // Add the MKext to the memory map.␊ |
400 | sprintf(segName, "DriversPackage-%lx", driversAddr);␊ |
401 | AllocateMemoryRange(segName, driversAddr, driversLength,␊ |
402 | kBootDriverTypeMKEXT);␊ |
403 | ␉␊ |
404 | return 0;␊ |
405 | }␊ |
406 | ␊ |
407 | //==========================================================================␊ |
408 | // LoadDriverPList␊ |
409 | ␊ |
410 | long␊ |
411 | LoadDriverPList( char * dirSpec, char * name, long bundleType )␊ |
412 | {␊ |
413 | long length, executablePathLength, bundlePathLength;␊ |
414 | ModulePtr module;␊ |
415 | TagPtr personalities;␊ |
416 | char * buffer = 0;␊ |
417 | char * tmpExecutablePath = 0;␊ |
418 | char * tmpBundlePath = 0;␊ |
419 | long ret = -1;␊ |
420 | ␉␊ |
421 | do {␊ |
422 | // Save the driver path.␊ |
423 | ␊ |
424 | sprintf(gFileSpec, "%s/%s/%s", dirSpec, name,␊ |
425 | (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");␊ |
426 | executablePathLength = strlen(gFileSpec) + 1;␊ |
427 | ␉␉␊ |
428 | tmpExecutablePath = malloc(executablePathLength);␊ |
429 | if (tmpExecutablePath == 0) break;␊ |
430 | ␉␉␊ |
431 | strcpy(tmpExecutablePath, gFileSpec);␊ |
432 | ␉␉␊ |
433 | sprintf(gFileSpec, "%s/%s", dirSpec, name);␊ |
434 | bundlePathLength = strlen(gFileSpec) + 1;␊ |
435 | ␉␉␊ |
436 | tmpBundlePath = malloc(bundlePathLength);␊ |
437 | if (tmpBundlePath == 0) break;␊ |
438 | ␉␉␊ |
439 | strcpy(tmpBundlePath, gFileSpec);␊ |
440 | ␉␉␊ |
441 | // Construct the file spec to the plist, then load it.␊ |
442 | ␉␉␊ |
443 | sprintf(gFileSpec, "%s/%s/%sInfo.plist", dirSpec, name,␊ |
444 | (bundleType == kCFBundleType2) ? "Contents/" : "");␊ |
445 | ␉␉␊ |
446 | length = LoadFile(gFileSpec);␊ |
447 | if (length == -1) break;␊ |
448 | ␉␉␊ |
449 | length = length + 1;␊ |
450 | buffer = malloc(length);␊ |
451 | if (buffer == 0) break;␊ |
452 | ␉␉␊ |
453 | strlcpy(buffer, (char *)kLoadAddr, length);␊ |
454 | ␉␉␊ |
455 | // Parse the plist.␊ |
456 | ␉␉␊ |
457 | ret = ParseXML(buffer, &module, &personalities);␊ |
458 | if (ret != 0) { break; }␊ |
459 | ␉␉␊ |
460 | // Allocate memory for the driver path and the plist.␊ |
461 | ␉␉␊ |
462 | module->executablePath = tmpExecutablePath;␊ |
463 | module->bundlePath = tmpBundlePath;␊ |
464 | module->bundlePathLength = bundlePathLength;␊ |
465 | module->plistAddr = malloc(length);␊ |
466 | ␉␉␊ |
467 | if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))␊ |
468 | break;␊ |
469 | ␉␉␊ |
470 | // Save the driver path in the module.␊ |
471 | //strcpy(module->driverPath, tmpDriverPath);␊ |
472 | tmpExecutablePath = 0;␊ |
473 | tmpBundlePath = 0;␊ |
474 | ␉␉␊ |
475 | // Add the plist to the module.␊ |
476 | ␉␉␊ |
477 | strlcpy(module->plistAddr, (char *)kLoadAddr, length);␊ |
478 | module->plistLength = length;␊ |
479 | ␉␉␊ |
480 | // Add the module to the end of the module list.␊ |
481 | ␊ |
482 | if (gModuleHead == 0)␊ |
483 | gModuleHead = module;␊ |
484 | else␊ |
485 | gModuleTail->nextModule = module;␊ |
486 | gModuleTail = module;␊ |
487 | ␉␉␊ |
488 | // Add the persionalities to the personality list.␊ |
489 | ␉␉␊ |
490 | if (personalities) personalities = personalities->tag;␊ |
491 | while (personalities != 0)␊ |
492 | {␊ |
493 | if (gPersonalityHead == 0)␊ |
494 | gPersonalityHead = personalities->tag;␊ |
495 | else␊ |
496 | gPersonalityTail->tagNext = personalities->tag;␊ |
497 | ␊ |
498 | gPersonalityTail = personalities->tag;␊ |
499 | personalities = personalities->tagNext;␊ |
500 | }␊ |
501 | ␊ |
502 | ret = 0;␊ |
503 | }␊ |
504 | while (0);␊ |
505 | ␊ |
506 | if ( buffer ) free( buffer );␊ |
507 | if ( tmpExecutablePath ) free( tmpExecutablePath );␊ |
508 | if ( tmpBundlePath ) free( tmpBundlePath );␊ |
509 | ␉␊ |
510 | return ret;␊ |
511 | }␊ |
512 | ␊ |
513 | ␊ |
514 | //==========================================================================␊ |
515 | // LoadMatchedModules␊ |
516 | ␊ |
517 | long LoadMatchedModules( void )␊ |
518 | {␊ |
519 | TagPtr prop;␊ |
520 | ModulePtr module;␊ |
521 | char *fileName, segName[32];␊ |
522 | DriverInfoPtr driver;␊ |
523 | long length, driverAddr, driverLength;␊ |
524 | void *executableAddr = 0;␊ |
525 | ␉␊ |
526 | ␉␊ |
527 | module = gModuleHead;␊ |
528 | ␉␊ |
529 | while (module != 0)␊ |
530 | {␊ |
531 | if (module->willLoad)␊ |
532 | {␊ |
533 | prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);␊ |
534 | ␉␉␉␊ |
535 | if (prop != 0)␊ |
536 | {␊ |
537 | fileName = prop->string;␊ |
538 | sprintf(gFileSpec, "%s%s", module->executablePath, fileName);␊ |
539 | length = LoadThinFatFile(gFileSpec, &executableAddr);␊ |
540 | ␉␉␉␉if (length == 0)␊ |
541 | ␉␉␉␉{␊ |
542 | ␉␉␉␉␉length = LoadFile(gFileSpec);␊ |
543 | ␉␉␉␉␉executableAddr = (void *)kLoadAddr;␊ |
544 | ␉␉␉␉}␊ |
545 | //printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getc();␊ |
546 | }␊ |
547 | else␊ |
548 | length = 0;␊ |
549 | ␉␉␉␊ |
550 | if (length != -1)␊ |
551 | {␊ |
552 | ␉␉␉␉//driverModuleAddr = (void *)kLoadAddr;␊ |
553 | //if (length != 0)␊ |
554 | //{␊ |
555 | ␉␉␉␉// ThinFatFile(&driverModuleAddr, &length);␊ |
556 | ␉␉␉␉//}␊ |
557 | ␉␉␉␉␊ |
558 | // Make make in the image area.␊ |
559 | ␉␉␉␉␊ |
560 | ␉␉␉␉execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);␊ |
561 | ␉␉␉␉␊ |
562 | driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;␊ |
563 | driverAddr = AllocateKernelMemory(driverLength);␊ |
564 | ␉␉␉␉␊ |
565 | // Set up the DriverInfo.␊ |
566 | driver = (DriverInfoPtr)driverAddr;␊ |
567 | driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));␊ |
568 | driver->plistLength = module->plistLength;␊ |
569 | if (length != 0)␊ |
570 | {␊ |
571 | driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +␊ |
572 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ module->plistLength);␊ |
573 | driver->executableLength = length;␊ |
574 | }␊ |
575 | else␊ |
576 | {␊ |
577 | driver->executableAddr = 0;␊ |
578 | driver->executableLength = 0;␊ |
579 | }␊ |
580 | driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +␊ |
581 | ␉␉␉␉␉␉␉␉␉␉␉␉ module->plistLength + driver->executableLength);␊ |
582 | driver->bundlePathLength = module->bundlePathLength;␊ |
583 | ␉␉␉␉␊ |
584 | // Save the plist, module and bundle.␊ |
585 | strcpy(driver->plistAddr, module->plistAddr);␊ |
586 | if (length != 0)␊ |
587 | {␊ |
588 | memcpy(driver->executableAddr, executableAddr, length);␊ |
589 | }␊ |
590 | strcpy(driver->bundlePathAddr, module->bundlePath);␊ |
591 | ␉␉␉␉␊ |
592 | // Add an entry to the memory map.␊ |
593 | sprintf(segName, "Driver-%lx", (unsigned long)driver);␊ |
594 | AllocateMemoryRange(segName, driverAddr, driverLength,␊ |
595 | kBootDriverTypeKEXT);␊ |
596 | }␊ |
597 | }␊ |
598 | module = module->nextModule;␊ |
599 | }␊ |
600 | ␉␊ |
601 | return 0;␊ |
602 | }␊ |
603 | ␊ |
604 | //==========================================================================␊ |
605 | // MatchPersonalities␊ |
606 | ␊ |
607 | long MatchPersonalities( void )␊ |
608 | {␊ |
609 | /* IONameMatch support not implemented */␊ |
610 | return 0;␊ |
611 | }␊ |
612 | ␊ |
613 | //==========================================================================␊ |
614 | // MatchLibraries␊ |
615 | ␊ |
616 | long MatchLibraries( void )␊ |
617 | {␊ |
618 | TagPtr prop, prop2;␊ |
619 | ModulePtr module, module2;␊ |
620 | long done;␊ |
621 | ␉␊ |
622 | do {␊ |
623 | done = 1;␊ |
624 | module = gModuleHead;␊ |
625 | ␊ |
626 | while (module != 0)␊ |
627 | {␊ |
628 | if (module->willLoad == 1)␊ |
629 | {␊ |
630 | prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);␊ |
631 | if (prop != 0)␊ |
632 | {␊ |
633 | prop = prop->tag;␊ |
634 | while (prop != 0)␊ |
635 | {␊ |
636 | module2 = gModuleHead;␊ |
637 | while (module2 != 0)␊ |
638 | {␊ |
639 | prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);␊ |
640 | if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))␊ |
641 | {␊ |
642 | if (module2->willLoad == 0) module2->willLoad = 1;␊ |
643 | break;␊ |
644 | }␊ |
645 | module2 = module2->nextModule;␊ |
646 | }␊ |
647 | prop = prop->tagNext;␊ |
648 | }␊ |
649 | }␊ |
650 | module->willLoad = 2;␊ |
651 | done = 0;␊ |
652 | }␊ |
653 | module = module->nextModule;␊ |
654 | }␊ |
655 | }␊ |
656 | while (!done);␊ |
657 | ␉␊ |
658 | return 0;␊ |
659 | }␊ |
660 | ␊ |
661 | ␊ |
662 | //==========================================================================␊ |
663 | // FindModule␊ |
664 | ␊ |
665 | #if NOTDEF␊ |
666 | static ModulePtr␊ |
667 | FindModule( char * name )␊ |
668 | {␊ |
669 | ModulePtr module;␊ |
670 | TagPtr prop;␊ |
671 | ␊ |
672 | module = gModuleHead;␊ |
673 | ␊ |
674 | while (module != 0)␊ |
675 | {␊ |
676 | prop = GetProperty(module->dict, kPropCFBundleIdentifier);␊ |
677 | if ((prop != 0) && !strcmp(name, prop->string)) break;␊ |
678 | module = module->nextModule;␊ |
679 | }␊ |
680 | ␊ |
681 | return module;␊ |
682 | }␊ |
683 | #endif /* NOTDEF */␊ |
684 | ␊ |
685 | //==========================================================================␊ |
686 | // ParseXML␊ |
687 | ␊ |
688 | static long␊ |
689 | ParseXML( char * buffer, ModulePtr * module, TagPtr * personalities )␊ |
690 | {␊ |
691 | ␉long length, pos;␊ |
692 | ␉TagPtr moduleDict, required;␊ |
693 | ␉ModulePtr tmpModule;␊ |
694 | ␉␊ |
695 | pos = 0;␊ |
696 | ␉␊ |
697 | while (1)␊ |
698 | {␊ |
699 | length = XMLParseNextTag(buffer + pos, &moduleDict);␊ |
700 | if (length == -1) break;␊ |
701 | ␉␉␊ |
702 | pos += length;␊ |
703 | ␉␉␊ |
704 | if (moduleDict == 0) continue;␊ |
705 | if (moduleDict->type == kTagTypeDict) break;␊ |
706 | ␉␉␊ |
707 | XMLFreeTag(moduleDict);␊ |
708 | }␊ |
709 | ␉␊ |
710 | if (length == -1) return -1;␊ |
711 | ␉␊ |
712 | required = XMLGetProperty(moduleDict, kPropOSBundleRequired);␊ |
713 | if ( (required == 0) ||␊ |
714 | ␉␉(required->type != kTagTypeString) ||␊ |
715 | ␉␉!strcmp(required->string, "Safe Boot"))␊ |
716 | {␊ |
717 | XMLFreeTag(moduleDict);␊ |
718 | return -2;␊ |
719 | }␊ |
720 | ␉␊ |
721 | tmpModule = malloc(sizeof(Module));␊ |
722 | if (tmpModule == 0)␊ |
723 | {␊ |
724 | XMLFreeTag(moduleDict);␊ |
725 | return -1;␊ |
726 | }␊ |
727 | tmpModule->dict = moduleDict;␊ |
728 | ␉␊ |
729 | // For now, load any module that has OSBundleRequired != "Safe Boot".␊ |
730 | ␉␊ |
731 | tmpModule->willLoad = 1;␊ |
732 | ␉␊ |
733 | *module = tmpModule;␊ |
734 | ␉␊ |
735 | // Get the personalities.␊ |
736 | ␉␊ |
737 | *personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);␊ |
738 | ␉␊ |
739 | return 0;␊ |
740 | }␊ |
741 | ␊ |
742 | #if NOTDEF␊ |
743 | static char gPlatformName[64];␊ |
744 | #endif␊ |
745 | ␊ |
746 | long ␊ |
747 | DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)␊ |
748 | {␊ |
749 | long ret;␊ |
750 | compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary;␊ |
751 | u_int32_t uncompressed_size, size;␊ |
752 | void *buffer;␊ |
753 | ␉unsigned long len;␊ |
754 | ␉␊ |
755 | #if 0␊ |
756 | printf("kernel header:\n");␊ |
757 | printf("signature: 0x%x\n", kernel_header->signature);␊ |
758 | printf("compress_type: 0x%x\n", kernel_header->compress_type);␊ |
759 | printf("adler32: 0x%x\n", kernel_header->adler32);␊ |
760 | printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);␊ |
761 | printf("compressed_size: 0x%x\n", kernel_header->compressed_size);␊ |
762 | getc();␊ |
763 | #endif␊ |
764 | ␉␊ |
765 | if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) {␊ |
766 | if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) {␊ |
767 | error("kernel compression is bad\n");␊ |
768 | return -1;␊ |
769 | }␊ |
770 | #if NOTDEF␊ |
771 | if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))␊ |
772 | return -1;␊ |
773 | if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))␊ |
774 | return -1;␊ |
775 | #endif␊ |
776 | ␉␉␊ |
777 | uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);␊ |
778 | binary = buffer = malloc(uncompressed_size);␊ |
779 | ␉␉␊ |
780 | size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],␊ |
781 | OSSwapBigToHostInt32(kernel_header->compressed_size));␊ |
782 | if (uncompressed_size != size) {␊ |
783 | error("size mismatch from lzss: %x\n", size);␊ |
784 | return -1;␊ |
785 | }␊ |
786 | if (OSSwapBigToHostInt32(kernel_header->adler32) !=␊ |
787 | Adler32(binary, uncompressed_size)) {␊ |
788 | printf("adler mismatch\n");␊ |
789 | return -1;␊ |
790 | }␊ |
791 | }␊ |
792 | ␉␊ |
793 | ␉ret = ThinFatFile(&binary, &len);␊ |
794 | ␉if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)␊ |
795 | ␉{␊ |
796 | ␉␉archCpuType=CPU_TYPE_I386;␊ |
797 | ␉␉ret = ThinFatFile(&binary, &len);␊ |
798 | ␉}␊ |
799 | ␉␊ |
800 | ␉//patch_kernel(binary);␊ |
801 | ␉␊ |
802 | ␉ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
803 | ␉␊ |
804 | ␉if (ret<0 && archCpuType==CPU_TYPE_X86_64)␊ |
805 | ␉{␊ |
806 | ␉␉archCpuType=CPU_TYPE_I386;␊ |
807 | ␉␉ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
808 | ␉}␊ |
809 | ␉␊ |
810 | ␉␊ |
811 | ␉return ret;␊ |
812 | }␊ |
813 |