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, time, time2;
283charaltDirSpec[512];
284
285snprintf(altDirSpec, sizeof(altDirSpec), "%s%s", dirSpec, extDirSpec);
286ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
287
288if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
289{
290ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
291
292if ((ret != 0)
293|| ((flags & kFileTypeMask) != kFileTypeDirectory)
294|| (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
295{
296snprintf(gDriverSpec, sizeof(altDirSpec) + 18, "%sExtensions.mkext", altDirSpec);
297verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
298
299if (LoadDriverMKext(gDriverSpec) == 0)
300{
301return 0;
302}
303}
304}
305return -1;
306}
307
308//==========================================================================
309// FileLoadDrivers
310
311long FileLoadDrivers( char * dirSpec, long plugin )
312{
313long ret, length, flags, time, bundleType;
314long long index;
315long result = -1;
316const char * name;
317
318if ( !plugin )
319{
320// First try 10.6's path for loading Extensions.mkext.
321if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0) {
322return 0;
323}
324
325// Next try the legacy path.
326else if (FileLoadMKext(dirSpec, "") == 0)
327{
328return 0;
329}
330
331strcat(dirSpec, "Extensions");
332}
333
334index = 0;
335while (1)
336{
337ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
338if (ret == -1) {
339break;
340}
341
342// Make sure this is a directory.
343if ((flags & kFileTypeMask) != kFileTypeDirectory)
344{
345continue;
346}
347
348// Make sure this is a kext.
349length = strlen(name);
350if (strcmp(name + length - 5, ".kext"))
351{
352continue;
353}
354
355// Save the file name.
356strlcpy(gFileName, name, 4096);
357
358// Determine the bundle type.
359snprintf(gTempSpec, 4096, "%s/%s", dirSpec, gFileName);
360ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
361if (ret == 0)
362{
363bundleType = kCFBundleType2;
364}
365else
366{
367bundleType = kCFBundleType3;
368}
369
370if (!plugin)
371{
372snprintf(gDriverSpec, 4096, "%s/%s/%sPlugIns", dirSpec, gFileName, (bundleType == kCFBundleType2) ? "Contents/" : "");
373}
374
375ret = LoadDriverPList(dirSpec, gFileName, bundleType);
376
377if (result != 0)
378{
379result = ret;
380}
381
382if (!plugin)
383{
384FileLoadDrivers(gDriverSpec, 1);
385}
386}
387
388return result;
389}
390
391
392//==========================================================================
393//
394
395long NetLoadDrivers( char * dirSpec )
396{
397long tries;
398
399#if NODEF
400long cnt;
401
402// Get the name of the kernel
403cnt = strlen(gBootFile);
404while (cnt--) {
405if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ','))
406{
407cnt++;
408break;
409}
410}
411#endif
412
413// INTEL modification
414snprintf(gDriverSpec, 4096, "%s%s.mkext", dirSpec, bootInfo->bootFile);
415
416verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);
417
418tries = 3;
419while (tries--)
420{
421if (LoadDriverMKext(gDriverSpec) == 0)
422{
423break;
424}
425}
426if (tries == -1)
427{
428return -1;
429}
430
431return 0;
432}
433
434//==========================================================================
435// loadDriverMKext
436
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
483
484long
485LoadDriverPList( char * dirSpec, char * name, long bundleType )
486{
487long length, executablePathLength, bundlePathLength;
488ModulePtr module;
489TagPtr personalities;
490char * buffer = 0;
491char * tmpExecutablePath = 0;
492char * tmpBundlePath = 0;
493long ret = -1;
494
495do{
496// Save the driver path.
497
498if(name) {
499snprintf(gFileSpec, 4096, "%s/%s/%s", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
500} else {
501snprintf(gFileSpec, 4096, "%s/%s", dirSpec, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
502}
503executablePathLength = strlen(gFileSpec) + 1;
504
505tmpExecutablePath = malloc(executablePathLength);
506if (tmpExecutablePath == 0) {
507break;
508}
509strcpy(tmpExecutablePath, gFileSpec);
510
511if(name) {
512snprintf(gFileSpec, 4096, "%s/%s", dirSpec, name);
513} else {
514snprintf(gFileSpec, 4096, "%s", dirSpec);
515}
516bundlePathLength = strlen(gFileSpec) + 1;
517
518tmpBundlePath = malloc(bundlePathLength);
519if (tmpBundlePath == 0) {
520break;
521}
522
523strcpy(tmpBundlePath, gFileSpec);
524
525// Construct the file spec to the plist, then load it.
526
527if(name) {
528snprintf(gFileSpec, 4096, "%s/%s/%sInfo.plist", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/" : "");
529} else {
530snprintf(gFileSpec, 4096, "%s/%sInfo.plist", dirSpec, (bundleType == kCFBundleType2) ? "Contents/" : "");
531}
532
533length = LoadFile(gFileSpec);
534if (length == -1) {
535break;
536}
537length = length + 1;
538buffer = malloc(length);
539if (buffer == 0) {
540break;
541}
542strlcpy(buffer, (char *)kLoadAddr, length);
543
544// Parse the plist.
545
546ret = ParseXML(buffer, &module, &personalities);
547
548if (ret != 0) {
549break;
550}
551
552if (!module) // cparm
553{
554ret = -1;
555break;
556} // Should never happen but it will make the compiler happy
557
558// Allocate memory for the driver path and the plist.
559
560module->executablePath = tmpExecutablePath;
561module->bundlePath = tmpBundlePath;
562module->bundlePathLength = bundlePathLength;
563module->plistAddr = malloc(length);
564
565if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0)) {
566break;
567}
568
569// Save the driver path in the module.
570//strcpy(module->driverPath, tmpDriverPath);
571tmpExecutablePath = 0;
572tmpBundlePath = 0;
573
574// Add the plist to the module.
575
576strlcpy(module->plistAddr, (char *)kLoadAddr, length);
577module->plistLength = length;
578
579// Add the module to the end of the module list.
580
581if (gModuleHead == 0) {
582gModuleHead = module;
583} else {
584gModuleTail->nextModule = module;
585}
586gModuleTail = module;
587
588// Add the persionalities to the personality list.
589
590if (personalities) {
591personalities = personalities->tag;
592}
593while (personalities != 0)
594{
595if (gPersonalityHead == 0) {
596gPersonalityHead = personalities->tag;
597} else {
598gPersonalityTail->tagNext = personalities->tag;
599}
600
601gPersonalityTail = personalities->tag;
602personalities = personalities->tagNext;
603}
604
605ret = 0;
606}
607while (0);
608
609if ( buffer ) {
610free( buffer );
611}
612if ( tmpExecutablePath ) {
613free( tmpExecutablePath );
614}
615if ( tmpBundlePath ) {
616free( tmpBundlePath );
617}
618return ret;
619}
620
621
622//==========================================================================
623// LoadMatchedModules
624
625long
626LoadMatchedModules( void )
627{
628TagPtr prop;
629ModulePtr module;
630char *fileName, segName[32];
631DriverInfoPtr driver;
632long length, driverAddr, driverLength;
633void *executableAddr = 0;
634
635module = gModuleHead;
636
637while (module != 0)
638{
639if (module->willLoad)
640{
641prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
642
643if (prop != 0)
644{
645fileName = prop->string;
646snprintf(gFileSpec, 4096, "%s%s", module->executablePath, fileName);
647length = LoadThinFatFile(gFileSpec, &executableAddr);
648if (length == 0)
649{
650length = LoadFile(gFileSpec);
651executableAddr = (void *)kLoadAddr;
652}
653//printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getchar();
654}
655else
656length = 0;
657
658if (length != -1)
659{
660//driverModuleAddr = (void *)kLoadAddr;
661//if (length != 0)
662//{
663//ThinFatFile(&driverModuleAddr, &length);
664//}
665
666// Make make in the image area.
667
668execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
669
670driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
671driverAddr = AllocateKernelMemory(driverLength);
672
673// Set up the DriverInfo.
674driver = (DriverInfoPtr)driverAddr;
675driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
676driver->plistLength = module->plistLength;
677if (length != 0)
678{
679driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
680 module->plistLength);
681driver->executableLength = length;
682}
683else
684{
685driver->executableAddr = 0;
686driver->executableLength = 0;
687}
688driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
689 module->plistLength + driver->executableLength);
690driver->bundlePathLength = module->bundlePathLength;
691
692// Save the plist, module and bundle.
693strcpy(driver->plistAddr, module->plistAddr);
694if (length != 0)
695{
696memcpy(driver->executableAddr, executableAddr, length);
697}
698strcpy(driver->bundlePathAddr, module->bundlePath);
699
700// Add an entry to the memory map.
701snprintf(segName, sizeof(segName), "Driver-%lx", (unsigned long)driver);
702AllocateMemoryRange(segName, driverAddr, driverLength,
703kBootDriverTypeKEXT);
704}
705}
706module = module->nextModule;
707}
708
709return 0;
710}
711
712//==========================================================================
713// MatchPersonalities
714
715static long
716MatchPersonalities( void )
717{
718/* IONameMatch support not implemented */
719return 0;
720}
721
722//==========================================================================
723// MatchLibraries
724
725static long
726MatchLibraries( void )
727{
728TagPtr prop, prop2;
729ModulePtr module, module2;
730long done;
731
732do {
733done = 1;
734module = gModuleHead;
735
736while (module != 0)
737{
738if (module->willLoad == 1)
739{
740prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
741
742if (prop != 0)
743{
744prop = prop->tag;
745
746while (prop != 0)
747{
748module2 = gModuleHead;
749
750while (module2 != 0)
751{
752prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
753
754if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
755{
756if (module2->willLoad == 0)
757{
758module2->willLoad = 1;
759}
760break;
761}
762module2 = module2->nextModule;
763}
764prop = prop->tagNext;
765}
766}
767module->willLoad = 2;
768done = 0;
769}
770module = module->nextModule;
771}
772}
773while (!done);
774
775return 0;
776}
777
778
779//==========================================================================
780// FindModule
781
782#if NOTDEF
783static ModulePtr
784FindModule( char * name )
785{
786ModulePtr module;
787TagPtr prop;
788
789module = gModuleHead;
790
791while (module != 0)
792{
793prop = GetProperty(module->dict, kPropCFBundleIdentifier);
794
795if ((prop != 0) && !strcmp(name, prop->string))
796{
797break;
798}
799
800module = module->nextModule;
801}
802
803return module;
804}
805#endif /* NOTDEF */
806
807//==========================================================================
808// ParseXML
809
810static long
811ParseXML( char * buffer, ModulePtr * module, TagPtr * personalities )
812{
813long length, pos;
814TagPtr moduleDict, required;
815ModulePtr tmpModule;
816
817pos = 0;
818
819while (1)
820{
821length = XMLParseNextTag(buffer + pos, &moduleDict);
822if (length == -1)
823{
824break;
825}
826
827pos += length;
828
829if (moduleDict == 0)
830{
831continue;
832}
833if (moduleDict->type == kTagTypeDict)
834{
835break;
836}
837XMLFreeTag(moduleDict);
838}
839
840if (length == -1)
841{
842return -1;
843}
844
845required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
846
847if ( (required == 0) || (required->type != kTagTypeString) || !strcmp(required->string, "Safe Boot"))
848{
849XMLFreeTag(moduleDict);
850return -2;
851}
852
853tmpModule = malloc(sizeof(Module));
854if (tmpModule == 0)
855{
856XMLFreeTag(moduleDict);
857return -1;
858}
859tmpModule->dict = moduleDict;
860
861// For now, load any module that has OSBundleRequired != "Safe Boot".
862
863tmpModule->willLoad = 1;
864
865*module = tmpModule;
866
867// Get the personalities.
868
869*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
870
871return 0;
872}
873
874#if NOTDEF
875static char gPlatformName[64];
876#endif
877
878char *gDarwinBuildVerStr = "Darwin Kernel Version"; // Bungo
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;
885void *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{
900DBG("Decompressing Kernel: ");
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#if NOTDEF
909if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
910{
911return -1;
912}
913
914if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
915{
916return -1;
917}
918#endif
919uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
920binary = buffer = malloc(uncompressed_size);
921
922// MinusZwei
923size = 0;
924switch (kernel_header->compress_type)
925{
926case OSSwapBigToHostConstInt32('lzvn'):
927size = decompress_lzvn( binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
928break;
929
930case OSSwapBigToHostConstInt32('lzss'):
931size = decompress_lzss( (u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
932break;
933
934default:
935break;
936}
937// MinusZwei
938
939if (uncompressed_size != size)
940{
941if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
942{
943error("ERROR: size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size);
944}
945
946if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
947{
948error("ERROR: size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size);
949}
950
951return -1;
952}
953
954adler32 = Adler32(binary, uncompressed_size);
955if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
956{
957error("ERROR: adler mismatch (found: %x, expected: %x).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
958return -1;
959}
960
961DBG("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: no range checking, sorry
972size = 0;
973while (memcmp((uint8_t *)binary + size, (uint8_t *)gDarwinBuildVerStr, 21)) {
974size++;
975}
976gDarwinBuildVerStr = (char *)binary + size;
977
978// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
979execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL);
980
981ret = DecodeMachO(binary, rentry, raddr, rsize);
982if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
983{
984archCpuType = CPU_TYPE_I386;
985ret = DecodeMachO(binary, rentry, raddr, rsize);
986}
987
988return ret;
989}
990

Archive Download this file

Revision: 2456