Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2758