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