Chameleon

Chameleon Svn Source Tree

Root/branches/Bungo/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 {
77 unsigned long signature1;
78 unsigned long signature2;
79 unsigned long length;
80 unsigned long adler32;
81 unsigned long version;
82 unsigned long numDrivers;
83 unsigned long reserved1;
84 unsigned 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// Bungo:
120char gDarwinBuildVerStr[256] = "Darwin Kernel Version";
121
122/*static*/ unsigned long
123Adler32( unsigned char *buffer, long length )
124{
125long cnt;
126unsigned long result, lowHalf, highHalf;
127
128lowHalf = 1;
129highHalf = 0;
130
131for (cnt = 0; cnt < length; cnt++)
132{
133if ((cnt % 5000) == 0)
134{
135lowHalf %= 65521L;
136highHalf %= 65521L;
137}
138
139lowHalf += buffer[cnt];
140highHalf += lowHalf;
141}
142
143lowHalf %= 65521L;
144highHalf %= 65521L;
145
146result = (highHalf << 16) | lowHalf;
147
148return result;
149}
150
151//==========================================================================
152// InitDriverSupport
153
154static long InitDriverSupport( void )
155{
156gExtensionsSpec = malloc( 4096 );
157gDriverSpec = malloc( 4096 );
158gFileSpec = malloc( 4096 );
159gTempSpec = malloc( 4096 );
160gFileName = malloc( 4096 );
161
162if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName ) {
163stop("InitDriverSupport error");
164}
165
166return 0;
167}
168
169//==========================================================================
170// LoadDrivers
171
172long LoadDrivers( char * dirSpec )
173{
174char dirSpecExtra[1024];
175
176if ( InitDriverSupport() != 0 )
177{
178return 0;
179}
180
181// Load extra drivers if a hook has been installed.
182if (LoadExtraDrivers_p != NULL)
183{
184(*LoadExtraDrivers_p)(&FileLoadDrivers);
185}
186
187if ( gBootFileType == kNetworkDeviceType )
188{
189if (NetLoadDrivers(dirSpec) != 0)
190{
191error("LoadDrivers: Could not load drivers from the network\n");
192return -1;
193}
194}
195else if ( gBootFileType == kBlockDeviceType )
196{
197// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
198if (gRAMDiskVolume && !gRAMDiskBTAliased)
199{
200strcpy(dirSpecExtra, "rd(0,0)/Extra/");
201FileLoadDrivers(dirSpecExtra, 0);
202}
203
204// Next try to load Extra extensions from the selected root partition.
205strcpy(dirSpecExtra, "/Extra/");
206if (FileLoadDrivers(dirSpecExtra, 0) != 0)
207{
208// If failed, then try to load Extra extensions from the boot partition
209// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
210if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
211|| (gRAMDiskVolume && gRAMDiskBTAliased) )
212{
213// Next try a specfic OS version folder ie 10.5
214sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);
215if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
216// Next we'll try the base
217strcpy(dirSpecExtra, "bt(0,0)/Extra/");
218FileLoadDrivers(dirSpecExtra, 0);
219}
220}
221}
222if(!gHaveKernelCache)
223{
224// Don't load main driver (from /System/Library/Extentions) if gHaveKernelCache is set.
225// since these drivers will already be in the kernel cache.
226// NOTE: when gHaveKernelCache, xnu cannot (by default) load *any* extra kexts from the bootloader.
227// The /Extra code is not disabled in this case due to a kernel patch that allows for this to happen.
228
229// Also try to load Extensions from boot helper partitions.
230if (gBootVolume->flags & kBVFlagBooter) {
231strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
232if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
233strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");
234if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
235strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");
236FileLoadDrivers(dirSpecExtra, 0);
237}
238}
239}
240
241if (gMKextName[0] != '\0')
242{
243verbose("LoadDrivers: Loading from '%s'\n", gMKextName);
244if ( LoadDriverMKext(gMKextName) != 0 ) {
245error("Could not load %s\n", gMKextName);
246return -1;
247}
248}
249else
250{
251if (MacOSVerCurrent >= MacOSVer2Int("10.9")) { // issue 352
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
880long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
881{
882long ret = 0;
883compressed_kernel_header *kernel_header = (compressed_kernel_header *)binary;
884u_int32_t uncompressed_size = 0, size = 0, adler32 = 0;
885//void *buffer = NULL;
886unsigned long len = 0;
887
888/*#if 0
889printf("kernel header:\n");
890printf("signature: 0x%x\n", kernel_header->signature);
891printf("compress_type: 0x%x\n", kernel_header->compress_type);
892printf("adler32: 0x%x\n", kernel_header->adler32);
893printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
894printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
895getchar();
896#endif*/
897
898if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
899{
900verbose("Decompressing Kernel Cache");
901/*
902if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) &&
903 (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn')))
904{
905error("ERROR: kernel compression is bad!\n");
906return -1;
907}
908*/
909#if NOTDEF
910if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
911{
912return -1;
913}
914
915if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
916{
917return -1;
918}
919#endif
920uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
921binary /* = buffer */ = malloc(uncompressed_size);
922
923// MinusZwei
924size = 0;
925switch (kernel_header->compress_type)
926{
927case OSSwapBigToHostConstInt32('lzvn'):
928 verbose(" using 'lzvn': ");
929size = lzvn_decode((u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
930if (uncompressed_size != size)
931{
932 error("ERROR! Size mismatch from 'lzvn' (found: %d, expected: %d).\n", size, uncompressed_size);
933 return -1;
934 }
935break;
936
937case OSSwapBigToHostConstInt32('lzss'):
938 verbose(" using 'lzss': ");
939size = decompress_lzss((u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
940if (uncompressed_size != size)
941{
942 error("ERROR! Size mismatch from 'lzss' (found: %d, expected: %d).\n", size, uncompressed_size);
943 return -1;
944 }
945break;
946
947default:
948 verbose(": ");
949 uint32_t compress_type = OSSwapBigToHostInt32(kernel_header->compress_type);
950 error("ERROR! Unknown kernel compression type: '%c%c%c%c'!\n", ((char *)&compress_type)[0], ((char *)&compress_type)[1], ((char *)&compress_type)[2], ((char *)&compress_type)[3]);
951 return -1;
952}
953// MinusZwei
954
955adler32 = Adler32(binary, uncompressed_size);
956if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
957{
958error("ERROR! Adler mismatch (found: %X, expected: %X).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
959return -1;
960}
961 verbose("OK.\n");
962}
963
964ret = ThinFatFile(&binary, &len);
965if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
966{
967archCpuType=CPU_TYPE_I386;
968ret = ThinFatFile(&binary, &len);
969}
970
971 // Bungo: scan binary for Darwin Kernel Version string
972 uint32_t offset = 0;
973 //strncpy(gDarwinBuildVerStr, "Darwin Kernel Version", sizeof(gDarwinBuildVerStr));
974while ((offset < 0xFFFFFFFF - (uint32_t)binary - 256) && memcmp(binary + offset, gDarwinBuildVerStr, 21))
975{
976 offset++;
977 }
978 if (offset < 0xFFFFFFFF - (uint32_t)binary - 256)
979{
980 strncpy(gDarwinBuildVerStr, (char *)(binary + offset), sizeof(gDarwinBuildVerStr));
981}
982 else
983{
984 strcat(gDarwinBuildVerStr, ": Unknown");
985}
986
987// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
988execute_hook("DecodeKernel", (void *)binary, NULL, NULL, NULL);
989
990ret = DecodeMachO(binary, rentry, raddr, rsize);
991if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
992{
993archCpuType = CPU_TYPE_I386;
994ret = DecodeMachO(binary, rentry, raddr, rsize);
995}
996
997return ret;
998}
999

Archive Download this file

Revision: 2537