Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/boot2/drivers.c

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
45struct 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};
55typedef struct Module Module, *ModulePtr;
56
57struct DriverInfo {
58 char *plistAddr;
59 long plistLength;
60 void *executableAddr;
61 long executableLength;
62 void *bundlePathAddr;
63 long bundlePathLength;
64};
65typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
66
67#define kDriverPackageSignature1 'MKXT'
68#define kDriverPackageSignature2 'MOSX'
69
70struct 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};
80typedef struct DriversPackage DriversPackage;
81
82enum {
83 kCFBundleType2,
84 kCFBundleType3
85};
86
87long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
88
89/*static*/ unsigned long Adler32( unsigned char * buffer, long length );
90
91long FileLoadDrivers(char *dirSpec, long plugin);
92long NetLoadDrivers(char *dirSpec);
93long LoadDriverMKext(char *fileSpec);
94long LoadDriverPList(char *dirSpec, char *name, long bundleType);
95long LoadMatchedModules(void);
96
97static long MatchPersonalities(void);
98static long MatchLibraries(void);
99#ifdef NOTDEF
100static ModulePtr FindModule(char *name);
101static void ThinFatFile(void **loadAddrP, unsigned long *lengthP);
102#endif
103static long ParseXML(char *buffer, ModulePtr *module, TagPtr *personalities);
104static long InitDriverSupport(void);
105
106ModulePtr gModuleHead, gModuleTail;
107static TagPtr gPersonalityHead, gPersonalityTail;
108static char * gExtensionsSpec;
109static char * gDriverSpec;
110static char * gFileSpec;
111static char * gTempSpec;
112static char * gFileName;
113
114/*static*/ unsigned long
115Adler32( unsigned char * buffer, long length )
116{
117 long cnt;
118 unsigned long result, lowHalf, highHalf;
119
120 lowHalf = 1;
121 highHalf = 0;
122
123for ( 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
135lowHalf %= 65521L;
136highHalf %= 65521L;
137
138result = (highHalf << 16) | lowHalf;
139
140return result;
141}
142
143
144//==========================================================================
145// InitDriverSupport
146
147static long
148InitDriverSupport( 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
165long 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
270static long
271FileLoadMKext( const char * dirSpec, const char * extDirSpec )
272{
273longret, flags, time, time2;
274charaltDirSpec[512];
275
276sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec);
277ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
278
279if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
280{
281ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
282
283if ((ret != 0)
284|| ((flags & kFileTypeMask) != kFileTypeDirectory)
285|| (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
286{
287sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);
288verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
289
290if (LoadDriverMKext(gDriverSpec) == 0)
291return 0;
292}
293}
294return -1;
295}
296
297//==========================================================================
298// FileLoadDrivers
299
300long
301FileLoadDrivers( 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
362long
363NetLoadDrivers( 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
398long
399LoadDriverMKext( 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
413execute_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
444long
445LoadDriverPList( 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
551long
552LoadMatchedModules( void )
553{
554TagPtr prop;
555ModulePtr module;
556char *fileName, segName[32];
557DriverInfoPtr driver;
558long length, driverAddr, driverLength;
559void *executableAddr = 0;
560
561
562module = gModuleHead;
563
564while (module != 0)
565{
566if (module->willLoad)
567{
568prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
569
570if (prop != 0)
571{
572fileName = prop->string;
573sprintf(gFileSpec, "%s%s", module->executablePath, fileName);
574length = LoadThinFatFile(gFileSpec, &executableAddr);
575if (length == 0)
576{
577length = LoadFile(gFileSpec);
578executableAddr = (void *)kLoadAddr;
579}
580//printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getchar();
581}
582else
583length = 0;
584
585if (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
597driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
598driverAddr = AllocateKernelMemory(driverLength);
599
600// Set up the DriverInfo.
601driver = (DriverInfoPtr)driverAddr;
602driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
603driver->plistLength = module->plistLength;
604if (length != 0)
605{
606driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
607 module->plistLength);
608driver->executableLength = length;
609}
610else
611{
612driver->executableAddr = 0;
613driver->executableLength = 0;
614}
615driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
616 module->plistLength + driver->executableLength);
617driver->bundlePathLength = module->bundlePathLength;
618
619// Save the plist, module and bundle.
620strcpy(driver->plistAddr, module->plistAddr);
621if (length != 0)
622{
623memcpy(driver->executableAddr, executableAddr, length);
624}
625strcpy(driver->bundlePathAddr, module->bundlePath);
626
627// Add an entry to the memory map.
628sprintf(segName, "Driver-%lx", (unsigned long)driver);
629AllocateMemoryRange(segName, driverAddr, driverLength,
630kBootDriverTypeKEXT);
631}
632}
633module = module->nextModule;
634}
635
636return 0;
637}
638
639//==========================================================================
640// MatchPersonalities
641
642static long
643MatchPersonalities( void )
644{
645 /* IONameMatch support not implemented */
646 return 0;
647}
648
649//==========================================================================
650// MatchLibraries
651
652static long
653MatchLibraries( 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
703static ModulePtr
704FindModule( 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
725static long
726ParseXML( char * buffer, ModulePtr * module, TagPtr * personalities )
727{
728long length, pos;
729TagPtr moduleDict;
730ModulePtr 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
781static char gPlatformName[64];
782#endif
783
784long
785DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
786{
787long ret;
788compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary;
789u_int32_t uncompressed_size, size;
790void *buffer;
791unsigned long len;
792
793#if 0
794printf("kernel header:\n");
795printf("signature: 0x%x\n", kernel_header->signature);
796printf("compress_type: 0x%x\n", kernel_header->compress_type);
797printf("adler32: 0x%x\n", kernel_header->adler32);
798printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
799printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
800getchar();
801#endif
802
803if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
804{
805if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss'))
806{
807error("kernel compression is bad\n");
808return -1;
809}
810#if NOTDEF
811if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
812return -1;
813if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
814return -1;
815#endif
816uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
817binary = buffer = malloc(uncompressed_size);
818
819size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],
820 OSSwapBigToHostInt32(kernel_header->compressed_size));
821if (uncompressed_size != size) {
822error("size mismatch from lzss: %x\n", size);
823return -1;
824}
825
826if (OSSwapBigToHostInt32(kernel_header->adler32) !=
827Adler32(binary, uncompressed_size))
828{
829printf("adler mismatch\n");
830return -1;
831}
832}
833
834ret = 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
842execute_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

Archive Download this file

Revision: 1808