Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 284