Chameleon

Chameleon Svn Source Tree

Root/branches/andyvand/i386/boot2/drivers.c

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

Archive Download this file

Revision: 141