Chameleon

Chameleon Svn Source Tree

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

Source at commit 155 created 13 years 11 months ago.
By meklort, Support files updated (headers, memory map to fit large ramdisks, etc)
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: 155