Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2479