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
49bool gUseCommonAndOSdir = true;
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
95static inline 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
122static inline 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];
173long flags, ret=-1;
174u_int32_t time;
175
176if ( InitDriverSupport() != 0 )
177{
178return 0;
179}
180
181// ========================================
182gUseCommonAndOSdir = false; // old behavior
183
184ret = GetFileInfo("bt(0,0)/Extra/Extensions/", "Common", &flags, &time);
185
186// if the boot partition contains /Extra/Extensions/Common there is no need
187// to look else where because users will have also /Extra/Extensions/10.x
188if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory))
189{
190gUseCommonAndOSdir = true;
191verbose("/Extra/Extensions/Common and /Extra/Extensions/%s in use.\n", gBootVolume->OSVersion);
192//getchar();
193}
194// ========================================
195
196// Load extra drivers if a hook has been installed.
197if (LoadExtraDrivers_p != NULL)
198{
199(*LoadExtraDrivers_p)(&FileLoadDrivers);
200}
201
202if ( gBootFileType == kNetworkDeviceType )
203{
204if (NetLoadDrivers(dirSpec) != 0)
205{
206error("LoadDrivers: Could not load drivers from the network\n");
207return -1;
208}
209}
210else if ( gBootFileType == kBlockDeviceType )
211{
212// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
213if (gRAMDiskVolume && !gRAMDiskBTAliased)
214{
215strcpy(dirSpecExtra, "rd(0,0)/Extra/");
216FileLoadDrivers(dirSpecExtra, 0);
217}
218// verbose("Attempting to loading drivers from \"Extra\" repository:\n");
219
220// =====================================================================
221// Secondly try to load drivers from Common folder if in use
222if (gUseCommonAndOSdir)
223{
224sprintf(dirSpecExtra, "bt(0,0)/Extra/Extensions/Common");
225FileLoadDrivers(dirSpecExtra, 0);
226}
227// =====================================================================
228
229// Next try to load Extra extensions from the selected root partition.
230if (gUseCommonAndOSdir)
231{
232sprintf(dirSpecExtra, "bt(0,0)/Extra/Extensions/%s", gBootVolume->OSVersion);
233FileLoadDrivers(dirSpecExtra, 0);
234//verbose("gUseCommonAndOSdir = %s\n", dirSpecExtra);
235//getchar();
236}
237else
238{
239strlcpy(dirSpecExtra, "/Extra/", sizeof(dirSpecExtra));
240if (FileLoadDrivers(dirSpecExtra, 0) != 0)
241{
242// If failed, then try to load Extra extensions from the boot partition
243// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
244if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
245|| (gRAMDiskVolume && gRAMDiskBTAliased) )
246{
247// Next try a specfic OS version folder ie 10.12
248sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion[0]);
249if (FileLoadDrivers(dirSpecExtra, 0) != 0)
250{
251// Next we'll try the base
252strlcpy(dirSpecExtra, "bt(0,0)/Extra/", sizeof(dirSpecExtra));
253FileLoadDrivers(dirSpecExtra, 0);
254}
255}
256}
257}
258
259if(!gHaveKernelCache)
260{
261// Don't load main driver (from /System/Library/Extentions) if gHaveKernelCache is set.
262// since these drivers will already be in the kernel cache.
263// NOTE: when gHaveKernelCache, xnu cannot (by default) load *any* extra kexts from the bootloader.
264// The /Extra code is not disabled in this case due to a kernel patch that allows for this to happen.
265
266// Also try to load Extensions from boot helper partitions.
267if (gBootVolume->flags & kBVFlagBooter)
268{
269strlcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/", sizeof(dirSpecExtra));
270if (FileLoadDrivers(dirSpecExtra, 0) != 0)
271{
272strlcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/", sizeof(dirSpecExtra));
273if (FileLoadDrivers(dirSpecExtra, 0) != 0)
274{
275strlcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/", sizeof(dirSpecExtra));
276FileLoadDrivers(dirSpecExtra, 0);
277}
278}
279}
280
281if (gMKextName[0] != '\0')
282{
283verbose("LoadDrivers: Loading from '%s'\n", gMKextName);
284if ( LoadDriverMKext(gMKextName) != 0 )
285{
286error("Could not load %s\n", gMKextName);
287return -1;
288}
289}
290else
291{
292verbose("Attempting to load drivers from standard repositories:\n");
293
294if ( (gMacOSVersion[3] == '9') || ((gMacOSVersion[3] == '1') && ((gMacOSVersion[4] == '0') || (gMacOSVersion[4] == '1') || (gMacOSVersion[4] == '2') ) )) // issue 352
295{
296verbose("\t- Third party extensions search path: /Library/Extensions\n");
297strlcpy(gExtensionsSpec, dirSpec, 4087); /* 4096 - sizeof("Library/") mean 4096 - 9 = 4087 */
298strcat(gExtensionsSpec, gUseCommonAndOSdir ? "Library/Extensions" : "Library/");
299FileLoadDrivers(gExtensionsSpec, 0);
300}
301
302verbose("\t- Apple extensions search path: /System/Library/Extensions\n");
303strlcpy(gExtensionsSpec, dirSpec, 4080); /* 4096 - sizeof("System/Library/") mean 4096 -16 = 4080 */
304strcat(gExtensionsSpec, gUseCommonAndOSdir ? "System/Library/Extensions" : "System/Library/");
305FileLoadDrivers(gExtensionsSpec, 0);
306}
307
308}
309}
310else
311{
312return 0;
313}
314
315MatchPersonalities();
316
317MatchLibraries();
318
319LoadMatchedModules();
320
321return 0;
322}
323
324//==========================================================================
325// FileLoadMKext
326static long FileLoadMKext( const char *dirSpec, const char *extDirSpec )
327{
328longret, flags;
329u_int32_ttime, time2;
330charaltDirSpec[512];
331
332snprintf(altDirSpec, sizeof(altDirSpec), "%s%s", dirSpec, extDirSpec);
333ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
334
335if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
336{
337ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
338
339if ((ret != 0)
340|| ((flags & kFileTypeMask) != kFileTypeDirectory)
341|| (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
342{
343snprintf(gDriverSpec, sizeof(altDirSpec) + 18, "%sExtensions.mkext", altDirSpec);
344verbose("LoadDrivers: Loading from '%s'\n", gDriverSpec);
345
346if (LoadDriverMKext(gDriverSpec) == 0)
347{
348return 0;
349}
350}
351}
352return -1;
353}
354
355//==========================================================================
356// FileLoadDrivers
357long FileLoadDrivers( char *dirSpec, long plugin )
358{
359long longindex;
360longret, length, flags, bundleType;
361longresult = -1;
362u_int32_ttime;
363const char* name;
364
365if ( !plugin )
366{
367// First try 10.6's path for loading Extensions.mkext.
368if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0) {
369return 0;
370}
371
372// Next try the legacy path.
373else if (FileLoadMKext(dirSpec, "") == 0)
374{
375return 0;
376}
377
378if (!gUseCommonAndOSdir)
379{
380// means that we already provide a full path to the Extensions directory
381strcat(dirSpec, "Extensions");
382}
383}
384
385index = 0;
386while (1)
387{
388ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
389if (ret == -1) {
390break;
391}
392
393// Make sure this is a directory.
394if ((flags & kFileTypeMask) != kFileTypeDirectory)
395{
396continue;
397}
398
399// Make sure this is a kext.
400length = strlen(name);
401if (strncmp(name + length - 5, ".kext", sizeof(".kext") ))
402{
403continue;
404}
405
406// Save the file name.
407strlcpy(gFileName, name, 4096);
408
409// Determine the bundle type.
410snprintf(gTempSpec, 4096, "%s/%s", dirSpec, gFileName);
411ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
412if (ret == 0)
413{
414bundleType = kCFBundleType2;
415}
416else
417{
418bundleType = kCFBundleType3;
419}
420
421if (!plugin)
422{
423snprintf(gDriverSpec, 4096, "%s/%s/%sPlugIns", dirSpec, gFileName, (bundleType == kCFBundleType2) ? "Contents/" : "");
424}
425
426ret = LoadDriverPList(dirSpec, gFileName, bundleType);
427
428if (result != 0)
429{
430result = ret;
431}
432
433if (!plugin)
434{
435FileLoadDrivers(gDriverSpec, 1);
436}
437}
438
439return result;
440}
441
442//==========================================================================
443//
444long NetLoadDrivers( char *dirSpec )
445{
446long tries;
447
448#if NODEF
449long cnt;
450
451// Get the name of the kernel
452cnt = strlen(gBootFile);
453while (cnt--) {
454if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ','))
455{
456cnt++;
457break;
458}
459}
460#endif
461
462// INTEL modification
463snprintf(gDriverSpec, 4096, "%s%s.mkext", dirSpec, bootInfo->bootFile);
464
465verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);
466
467tries = 3;
468while (tries--)
469{
470if (LoadDriverMKext(gDriverSpec) == 0)
471{
472break;
473}
474}
475if (tries == -1)
476{
477return -1;
478}
479
480return 0;
481}
482
483//==========================================================================
484// loadDriverMKext
485long LoadDriverMKext( char *fileSpec )
486{
487unsigned longdriversAddr, driversLength;
488longlength;
489charsegName[32];
490DriversPackage*package;
491
492#define GetPackageElement(e) OSSwapBigToHostInt32(package->e)
493
494// Load the MKext.
495length = LoadThinFatFile(fileSpec, (void **)&package);
496if (length < sizeof (DriversPackage))
497{
498return -1;
499}
500
501// call hook to notify modules that the mkext has been loaded
502execute_hook("LoadDriverMKext", (void *)fileSpec, (void *)package, (void *) &length, NULL);
503
504
505// Verify the MKext.
506if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
507( GetPackageElement(signature2) != kDriverPackageSignature2) ||
508( GetPackageElement(length) > kLoadSize ) ||
509( GetPackageElement(adler32) !=
510Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
511{
512return -1;
513}
514
515// Make space for the MKext.
516driversLength = GetPackageElement(length);
517driversAddr = AllocateKernelMemory(driversLength);
518
519// Copy the MKext.
520memcpy((void *)driversAddr, (void *)package, driversLength);
521
522// Add the MKext to the memory map.
523snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
524AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);
525
526return 0;
527}
528
529//==========================================================================
530// LoadDriverPList
531long LoadDriverPList( char *dirSpec, char *name, long bundleType )
532{
533longlength, executablePathLength, bundlePathLength;
534ModulePtrmodule;
535TagPtrpersonalities;
536char*buffer = 0;
537char*tmpExecutablePath = 0;
538char*tmpBundlePath = 0;
539longret = -1;
540
541do {
542// Save the driver path.
543
544if(name)
545{
546snprintf(gFileSpec, 4096, "%s/%s/%s", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
547}
548else
549{
550snprintf(gFileSpec, 4096, "%s/%s", dirSpec, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
551}
552executablePathLength = strlen(gFileSpec) + 1;
553
554tmpExecutablePath = malloc(executablePathLength);
555if (tmpExecutablePath == 0) {
556break;
557}
558strlcpy(tmpExecutablePath, gFileSpec, executablePathLength);
559
560if(name)
561{
562snprintf(gFileSpec, 4096, "%s/%s", dirSpec, name);
563}
564else
565{
566strncpy(gFileSpec, dirSpec, 4096);
567}
568bundlePathLength = strlen(gFileSpec) + 1;
569
570tmpBundlePath = malloc(bundlePathLength);
571if (tmpBundlePath == 0)
572{
573break;
574}
575
576strlcpy(tmpBundlePath, gFileSpec, bundlePathLength);
577
578// Construct the file spec to the plist, then load it.
579
580if(name)
581{
582snprintf(gFileSpec, 4096, "%s/%s/%sInfo.plist", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/" : "");
583}
584else
585{
586snprintf(gFileSpec, 4096, "%s/%sInfo.plist", dirSpec, (bundleType == kCFBundleType2) ? "Contents/" : "");
587}
588
589length = LoadFile(gFileSpec);
590
591if (length == -1)
592{
593break;
594}
595
596length = length + 1;
597buffer = malloc(length);
598
599if (buffer == 0)
600{
601break;
602}
603
604strlcpy(buffer, (char *)kLoadAddr, length);
605
606// Parse the plist.
607
608ret = ParseXML(buffer, &module, &personalities);
609
610if (ret != 0) {
611break;
612}
613
614if (!module) // cparm
615{
616ret = -1;
617break;
618} // Should never happen but it will make the compiler happy
619
620// Allocate memory for the driver path and the plist.
621
622module->executablePath = tmpExecutablePath;
623module->bundlePath = tmpBundlePath;
624module->bundlePathLength = bundlePathLength;
625module->plistAddr = malloc(length);
626
627if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
628{
629break;
630}
631
632// Save the driver path in the module.
633//strcpy(module->driverPath, tmpDriverPath);
634tmpExecutablePath = 0;
635tmpBundlePath = 0;
636
637// Add the plist to the module.
638
639strlcpy(module->plistAddr, (char *)kLoadAddr, length);
640module->plistLength = length;
641
642// Add the module to the end of the module list.
643
644if (gModuleHead == 0) {
645gModuleHead = module;
646} else {
647gModuleTail->nextModule = module;
648}
649gModuleTail = module;
650
651// Add the persionalities to the personality list.
652
653if (personalities) {
654personalities = personalities->tag;
655}
656while (personalities != 0)
657{
658if (gPersonalityHead == 0) {
659gPersonalityHead = personalities->tag;
660} else {
661gPersonalityTail->tagNext = personalities->tag;
662}
663
664gPersonalityTail = personalities->tag;
665personalities = personalities->tagNext;
666}
667
668ret = 0;
669}
670while (0);
671
672if ( buffer ) {
673free( buffer );
674}
675if ( tmpExecutablePath ) {
676free( tmpExecutablePath );
677}
678if ( tmpBundlePath ) {
679free( tmpBundlePath );
680}
681return ret;
682}
683
684//==========================================================================
685// LoadMatchedModules
686long LoadMatchedModules( void )
687{
688TagPtrprop;
689ModulePtrmodule;
690char*fileName, segName[32];
691DriverInfoPtrdriver;
692longlength, driverAddr, driverLength;
693void*executableAddr = 0;
694
695module = gModuleHead;
696
697while (module != 0)
698{
699if (module->willLoad)
700{
701prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
702
703if (prop != 0)
704{
705fileName = prop->string;
706snprintf(gFileSpec, 4096, "%s%s", module->executablePath, fileName);
707
708length = LoadThinFatFile(gFileSpec, &executableAddr);
709if (length == 0)
710{
711length = LoadFile(gFileSpec);
712executableAddr = (void *)kLoadAddr;
713}
714//printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getchar();
715}
716else
717{
718length = 0;
719}
720
721if ((length != -1) && executableAddr)
722{
723// Make make in the image area.
724
725execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
726
727driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
728driverAddr = AllocateKernelMemory(driverLength);
729
730// Set up the DriverInfo.
731driver = (DriverInfoPtr)driverAddr;
732driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
733driver->plistLength = module->plistLength;
734
735if (length != 0)
736{
737driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
738 module->plistLength);
739driver->executableLength = length;
740}
741else
742{
743driver->executableAddr = 0;
744driver->executableLength = 0;
745}
746
747driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
748 module->plistLength + driver->executableLength);
749driver->bundlePathLength = module->bundlePathLength;
750
751// Save the plist, module and bundle.
752strlcpy(driver->plistAddr, module->plistAddr, driver->plistLength);
753
754if (length != 0)
755{
756memcpy(driver->executableAddr, executableAddr, length);
757}
758
759strlcpy(driver->bundlePathAddr, module->bundlePath, module->bundlePathLength);
760
761// Add an entry to the memory map.
762snprintf(segName, sizeof(segName), "Driver-%lx", (unsigned long)driver);
763AllocateMemoryRange(segName, driverAddr, driverLength,
764kBootDriverTypeKEXT);
765}
766}
767module = module->nextModule;
768}
769
770return 0;
771}
772
773//==========================================================================
774// MatchPersonalities
775static long MatchPersonalities( void )
776{
777/* IONameMatch support not implemented */
778return 0;
779}
780
781//==========================================================================
782// MatchLibraries
783static long MatchLibraries( void )
784{
785TagPtr prop;
786TagPtr prop2;
787ModulePtr module;
788ModulePtr module2;
789long done;
790
791do {
792done = 1;
793module = gModuleHead;
794
795while (module != 0)
796{
797if (module->willLoad == 1)
798{
799prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
800
801if (prop != 0)
802{
803prop = prop->tag;
804
805while (prop != 0)
806{
807module2 = gModuleHead;
808
809while (module2 != 0)
810{
811prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
812
813if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
814{
815if (module2->willLoad == 0)
816{
817module2->willLoad = 1;
818}
819break;
820}
821module2 = module2->nextModule;
822}
823prop = prop->tagNext;
824}
825}
826module->willLoad = 2;
827done = 0;
828}
829module = module->nextModule;
830}
831}
832while (!done);
833
834return 0;
835}
836
837//==========================================================================
838// FindModule
839
840#if NOTDEF
841static ModulePtr FindModule( char *name )
842{
843ModulePtr module;
844TagPtr prop;
845
846module = gModuleHead;
847
848while (module != 0)
849{
850prop = GetProperty(module->dict, kPropCFBundleIdentifier);
851
852if ((prop != 0) && !strcmp(name, prop->string))
853{
854break;
855}
856
857module = module->nextModule;
858}
859
860return module;
861}
862#endif /* NOTDEF */
863
864//==========================================================================
865// ParseXML
866static long ParseXML( char *buffer, ModulePtr *module, TagPtr *personalities )
867{
868longlength;
869longpos = 0;
870TagPtrmoduleDict;
871TagPtrrequired;
872ModulePtrtmpModule;
873
874while (1)
875{
876length = XMLParseNextTag(buffer + pos, &moduleDict);
877if (length == -1)
878{
879break;
880}
881
882pos += length;
883
884if (moduleDict == 0)
885{
886continue;
887}
888if (moduleDict->type == kTagTypeDict)
889{
890break;
891}
892XMLFreeTag(moduleDict);
893}
894
895if (length == -1)
896{
897return -1;
898}
899
900required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
901
902if ( (required == 0) || (required->type != kTagTypeString) || !strncmp(required->string, "Safe Boot", sizeof("Safe Boot")))
903{
904XMLFreeTag(moduleDict);
905return -2;
906}
907
908tmpModule = malloc(sizeof(Module));
909if (tmpModule == 0)
910{
911XMLFreeTag(moduleDict);
912return -1;
913}
914tmpModule->dict = moduleDict;
915
916// For now, load any module that has OSBundleRequired != "Safe Boot".
917
918tmpModule->willLoad = 1;
919
920*module = tmpModule;
921
922// Get the personalities.
923
924*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
925
926return 0;
927}
928
929#if NOTDEF
930static char gPlatformName[64];
931#endif
932
933long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
934{
935long ret = 0;
936compressed_kernel_header *kernel_header = (compressed_kernel_header *)binary;
937u_int32_t uncompressed_size = 0, size = 0, adler32 = 0;
938void *buffer = NULL;
939unsigned long len = 0;
940
941/*#if 0
942printf("kernel header:\n");
943printf("signature: 0x%x\n", kernel_header->signature);
944printf("compress_type: 0x%x\n", kernel_header->compress_type);
945printf("adler32: 0x%x\n", kernel_header->adler32);
946printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
947printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
948getchar();
949#endif*/
950
951if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
952{
953DBG("Decompressing Kernel Cache:\n");
954
955if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) &&
956(kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn')))
957{
958error("\tERROR: kernel compression is bad!\n");
959return -1;
960}
961
962if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
963{
964verbose ("\t- Decompressing Kernel Using lzss\n");
965}
966
967if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
968{
969verbose ("\t- Decompressing Kernel Using lzvn\n");
970}
971
972#if NOTDEF
973if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
974{
975return -1;
976}
977
978if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
979{
980return -1;
981}
982#endif
983uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
984binary = buffer = malloc(uncompressed_size);
985
986// MinusZwei
987size = 0;
988switch (kernel_header->compress_type)
989{
990case OSSwapBigToHostConstInt32('lzvn'):
991size = lzvn_decode(binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
992break;
993
994case OSSwapBigToHostConstInt32('lzss'):
995size = decompress_lzss((u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
996break;
997
998default:
999break;
1000}
1001// MinusZwei
1002
1003if (uncompressed_size != size)
1004{
1005if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1006{
1007error("ERROR! Size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size);
1008}
1009
1010if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1011{
1012error("ERROR! size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size);
1013}
1014
1015return -1;
1016}
1017
1018adler32 = Adler32(binary, uncompressed_size);
1019if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
1020{
1021error("ERROR! Adler mismatch (found: %X, expected: %X).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
1022return -1;
1023}
1024
1025DBG("\n");
1026}
1027
1028ret = ThinFatFile(&binary, &len);
1029if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
1030{
1031archCpuType=CPU_TYPE_I386;
1032ret = ThinFatFile(&binary, &len);
1033}
1034
1035// Bungo: scan binary for Darwin Kernel Version string
1036useDarwinVersion = true;
1037uint32_t offset = 0;
1038strncpy(gDarwinBuildVerStr, "Darwin Kernel Version", sizeof(gDarwinBuildVerStr));
1039
1040while ((offset < 0xFFFFFFFF - (uint32_t)binary - 256) && memcmp(binary + offset, gDarwinBuildVerStr, 21))
1041{
1042offset++;
1043}
1044if (offset < 0xFFFFFFFF - (uint32_t)binary - 256)
1045{
1046strncpy(gDarwinBuildVerStr, (char *)(binary + offset), sizeof(gDarwinBuildVerStr));
1047}
1048else
1049{
1050strcat(gDarwinBuildVerStr, ": Unknown");
1051useDarwinVersion = false;
1052}
1053// Micky1979 use Bungo gDarwinBuildVerStr and split into gDarwinMajor, gDarwinMinor and gDarwinRev
1054if (useDarwinVersion)
1055{
1056useDarwinVersion = false;
1057const char *pattern = strstr(gDarwinBuildVerStr, "Darwin Kernel Version ")+22;
1058const char *until = strstr(pattern, ":");
1059size_t vlen = until - pattern;
1060char *ver = (char *)malloc(sizeof(char)*(len+1));
1061strncpy(ver, pattern, vlen);
1062ver[vlen] = '\0';
1063char *delim;
1064char *temp;
1065gDarwinMajor = -1; gDarwinMinor = -1; gDarwinRev = -1;
1066if (ver != NULL)
1067{
1068temp = ver;
1069int count = 1;
1070while ((delim = strsep_c(&ver, ".")) != NULL)
1071{
1072switch (count)
1073{
1074case 1: gDarwinMajor = atoi(delim); break;
1075case 2: gDarwinMinor = atoi(delim); break;
1076case 3: gDarwinRev = atoi(delim); break;
1077default: break;
1078}
1079count ++;
1080}
1081free(temp);
1082}
1083
1084if (gDarwinMajor >= 0 && gDarwinMinor >= 0 && gDarwinRev >= 0)
1085{
1086useDarwinVersion = true;
1087}
1088
1089switch (gDarwinMajor)
1090{
1091case 10:
1092switch (gDarwinMinor)
1093{
1094case 0: kernelOSVer = 0xA060000; break;
1095case 1: kernelOSVer = 0xA060100; break;
1096case 2: kernelOSVer = 0xA060200; break;
1097case 3: kernelOSVer = 0xA060300; break;
1098case 4: kernelOSVer = 0xA060400; break;
1099case 5: kernelOSVer = 0xA060500; break;
1100case 6: kernelOSVer = 0xA060600; break;
1101case 7: kernelOSVer = 0xA060700; break;
1102case 8: kernelOSVer = 0xA060800; break;
1103default:kernelOSVer = 0xA060800; break; //Last known kernel
1104}
1105break;
1106case 11:
1107switch (gDarwinMinor)
1108{
1109case 0: kernelOSVer = 0xA070000; break;
1110case 1: kernelOSVer = 0xA070100; break;
1111case 2: kernelOSVer = 0xA070200; break;
1112case 3: kernelOSVer = 0xA070300; break;
1113case 4:
1114switch (gDarwinRev)
1115{
1116case 0: kernelOSVer = 0xA070400; break;
1117case 1: kernelOSVer = 0xA070400; break;
1118case 2: kernelOSVer = 0xA070500; break;
1119default:kernelOSVer = 0xA070500; break; //Last known kernel
1120}
1121default:kernelOSVer = 0xA070500; break; //Last known kernel
1122}
1123break;
1124case 12:
1125switch (gDarwinMinor)
1126{
1127case 0: kernelOSVer = 0xA080000; break;
1128case 1: kernelOSVer = 0xA080100; break;
1129case 2: kernelOSVer = 0xA080200; break;
1130case 3: kernelOSVer = 0xA080300; break;
1131case 4: kernelOSVer = 0xA080400; break;
1132case 5: kernelOSVer = 0xA080500; break; // 10.8.5
1133case 6: kernelOSVer = 0xA080500; break; // 10.8.5 update
1134default:kernelOSVer = 0xA080500; break; //Last known kernel
1135}
1136break;
1137case 13:
1138switch (gDarwinMinor)
1139{
1140case 0: kernelOSVer = 0xA090000;
1141switch (gDarwinRev)
1142{
1143case 0: kernelOSVer = 0xA090000; break;
1144case 1: kernelOSVer = 0xA090000; break; // never exist (or released)
1145case 2: kernelOSVer = 0xA090100; break;
1146default:kernelOSVer = 0xA090100; break; //Last known kernel
1147}
1148break;
1149case 1: kernelOSVer = 0xA090100; break; // never exist (or released)
1150case 2: kernelOSVer = 0xA090200; break;
1151case 3: kernelOSVer = 0xA090300; break;
1152case 4: kernelOSVer = 0xA090400; break;
1153case 5: kernelOSVer = 0xA090500; break;
1154default:kernelOSVer = 0xA090500; break; //Last known kernel
1155}
1156break;
1157case 14:
1158switch (gDarwinMinor)
1159{
1160case 0: kernelOSVer = 0xA0A0000; break; // same kernel of 10.10.1
1161case 1: kernelOSVer = 0xA0A0100; break; // same kernel of 10.10
1162case 2: kernelOSVer = 0xA0A0200; break;
1163case 3: kernelOSVer = 0xA0A0300; break;
1164case 4: kernelOSVer = 0xA0A0400; break;
1165case 5: kernelOSVer = 0xA0A0500; break;
1166default:kernelOSVer = 0xA0A0500; break; //Last known kernel
1167}
1168break;
1169case 15: /* El Capitan */
1170switch (gDarwinMinor)
1171{
1172case 0: kernelOSVer = 0xA0B0000; break;
1173case 1: kernelOSVer = 0xA0B0100; break;
1174case 2: kernelOSVer = 0xA0B0200; break;
1175case 3: kernelOSVer = 0xA0B0300; break;
1176case 4: kernelOSVer = 0xA0B0400; break;
1177case 5: kernelOSVer = 0xA0B0500; break;
1178case 6: kernelOSVer = 0xA0B0600; break;
1179default:kernelOSVer = 0xA0B0600; break; //Last known kernel (add here updates)
1180}
1181break;
1182case 16: /* Sierra */
1183switch (gDarwinMinor)
1184{
1185case 0: kernelOSVer = 0xA0C0000; break;
1186case 1: kernelOSVer = 0xA0C0100; break;
1187case 2: kernelOSVer = 0xA0C0200; break;
1188case 3: kernelOSVer = 0xA0C0200; break;
1189case 4: kernelOSVer = 0xA0C0300; break;
1190case 5: kernelOSVer = 0xA0C0400; break;
1191default:kernelOSVer = 0xA0C0400; break; //Last known kernel (add here updates)
1192}
1193break;
1194default:
1195kernelOSVer = 0xA0C0400;
1196break; //Last known kernel is Sierra 10.12.4
1197}
1198}
1199else
1200{
1201switch (MacOSVerCurrent)
1202{
1203// Snow
1204case 0xA060000: gDarwinMajor = 10; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.6
1205case 0xA060100: gDarwinMajor = 10; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.6.1
1206case 0xA060200: gDarwinMajor = 10; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.6.2
1207case 0xA060300: gDarwinMajor = 10; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.6.3
1208case 0xA060400: gDarwinMajor = 10; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.6.4
1209case 0xA060500: gDarwinMajor = 10; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.6.5
1210case 0xA060600: gDarwinMajor = 10; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.6.6
1211case 0xA060700: gDarwinMajor = 10; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.6.7
1212case 0xA060800: gDarwinMajor = 10; gDarwinMinor = 8; gDarwinRev = 0; break; // 10.6.8
1213// Lion
1214case 0xA070000: gDarwinMajor = 11; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.7
1215case 0xA070100: gDarwinMajor = 11; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.7.1
1216case 0xA070200: gDarwinMajor = 11; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.7.2
1217case 0xA070300: gDarwinMajor = 11; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.7.3
1218case 0xA070400: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.7.4
1219case 0xA070500: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 2; break; // 10.7.5
1220// ML
1221case 0xA080000: gDarwinMajor = 12; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.8
1222case 0xA080100: gDarwinMajor = 12; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.8.1
1223case 0xA080200: gDarwinMajor = 12; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.8.2
1224case 0xA080300: gDarwinMajor = 12; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.8.3
1225case 0xA080400: gDarwinMajor = 12; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.8.4
1226case 0xA080500: gDarwinMajor = 12; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.8.5
1227// Mavericks
1228case 0xA090000: gDarwinMajor = 13; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.9
1229case 0xA090100: gDarwinMajor = 13; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.9.1
1230case 0xA090200: gDarwinMajor = 13; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.9.2
1231case 0xA090300: gDarwinMajor = 13; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.9.3
1232case 0xA090400: gDarwinMajor = 13; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.9.4
1233case 0xA090500: gDarwinMajor = 13; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.9.5
1234// Yosemite
1235case 0xA0A0000: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10
1236case 0xA0A0100: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10.1
1237case 0xA0A0200: gDarwinMajor = 14; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.10.2
1238case 0xA0A0300: gDarwinMajor = 14; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.10.3
1239case 0xA0A0400: gDarwinMajor = 14; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.10.4
1240case 0xA0A0500: gDarwinMajor = 14; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.10.5
1241// El Capitan
1242case 0xA0B0000: gDarwinMajor = 15; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.11
1243case 0xA0B0100: gDarwinMajor = 15; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.11.1
1244case 0xA0B0200: gDarwinMajor = 15; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.11.2
1245case 0xA0B0300: gDarwinMajor = 15; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.11.3
1246case 0xA0B0400: gDarwinMajor = 15; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.11.4
1247case 0xA0B0500: gDarwinMajor = 15; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.11.5
1248case 0xA0B0600: gDarwinMajor = 15; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.11.6
1249// Sierra
1250case 0xA0C0000: gDarwinMajor = 16; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.12
1251case 0xA0C0100: gDarwinMajor = 16; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.12.1
1252case 0xA0C0200: gDarwinMajor = 16; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.12.2
1253case 0xA0C0300: gDarwinMajor = 16; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.12.3
1254case 0xA0C0400: gDarwinMajor = 16; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.12.4
1255// default = last known kernel
1256default: gDarwinMajor = 16; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.12.4;
1257}
1258}
1259
1260// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
1261execute_hook("DecodeKernel", (void *)binary, NULL, NULL, NULL);
1262
1263/* ================================================================ */
1264
1265ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1266if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
1267{
1268archCpuType = CPU_TYPE_I386;
1269ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1270}
1271
1272return ret;
1273}
1274

Archive Download this file

Revision: 2869