Chameleon

Chameleon Commit Details

Date:2011-08-14 11:22:58 (12 years 8 months ago)
Author:Azimutz
Commit:1374
Parents: 1373
Message:Revert and fix.
Changes:
M/trunk/i386/boot2/boot.c

File differences

trunk/i386/boot2/boot.c
66
77
88
9
9
1010
1111
1212
......
2121
2222
2323
24
2425
2526
2627
2728
28
29
2930
3031
3132
3233
33
34
3435
35
36
37
36
37
38
3839
39
40
4041
4142
4243
......
4950
5051
5152
52
5353
5454
5555
......
7171
7272
7373
74
74
7575
76
76
7777
78
79
80
81
78
79
80
81
8282
8383
8484
......
101101
102102
103103
104
104
105105
106106
107107
......
115115
116116
117117
118
118
119119
120120
121121
......
148148
149149
150150
151
152
151
152
153153
154
155
154
155
156156
157
158
157
158
159159
160160
161161
......
163163
164164
165165
166
166
167167
168168
169169
......
186186
187187
188188
189
190
191
192
193
194
195
196
197
189
190
191
192
193
194
195
196
197
198
198199
199200
200201
201
202
202
203203
204204
205205
......
208208
209209
210210
211
211
212
212213
213214
214215
215216
216217
217
218
219218
220219
221220
222
223
224221
225222
226
223
227224
228225
229226
......
245242
246243
247244
248
249
245
246
250247
251248
252249
253250
254251
255252
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
276273
277
278
279
280
274
275
276
277
281278
282
279
283280
284
281
285282
286
283
287284
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
343342
344343
345
344
346345
347
348
349
346
347
348
349
350
350351
351
352
352353
353354
354355
......
357358
358359
359360
360
361
362
363
364
365
366
367
368
369
370
371
372
373
361
362
363
364
365
366
367
368
369
370
371
372
373
374
374375
375
376
377
378376
379
380
381
382
383
384
385
386
377
378
387379
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
380
408381
409
382
383
410384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
411412
412
413
413414
414415
415416
......
422423
423424
424425
425
426
426427
427428
428429
429430
430431
431
432
432433
433434
434435
435436
436437
437
438
438
439
439440
440441
441442
442443
443
444
444445
445446
446
447
447448
448449
449450
450451
451452
452453
453
454
454455
455456
456457
......
468469
469470
470471
471
472
472473
473474
474475
......
480481
481482
482483
483
484
485
484
485
486
487
486488
487489
488
490
489491
490492
491493
492
494
493495
494
496
495497
496
497
498
499
500
501
498
499
500
501
502
503
502504
503505
504506
......
509511
510512
511513
512
513
514
515
516
517
518
519
520
521514
522515
523516
......
526519
527520
528521
529
522
523
530524
531525
532526
......
545539
546540
547541
548
549
550
542
543
544
551545
552
553
554
555
556
546
547
548
549
550
557551
558552
559
560
561
562
563
564
565
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
566584
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
585
586
587
588
592589
593
594
595
590
591
592
596593
597594
598
595
599596
600597
601598
602
603
599
600
604601
605602
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
647644
648
645
649646
650
651
652
653
654
655
656
657
658
659
660
661
662
647
648
649
650
651
652
653
654
655
656
657
658
659
660
663661
664
665
662
663
666664
667
668
665
666
669667
670
668
671669
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
670
671
672
673
674
675
676
677
678
688679
689
680
690681
691
682
683
684
685
686
687
688
689
690
692691
693
692
694693
695694
696695
697
696
698697
699698
700699
701700
702
703
704
705
706
707
708
709
710
711
712
713
701
702
703
704
705
706
707
708
709
710
711
712
714713
715714
716715
717716
718717
719
718
719
720720
721721
722722
......
725725
726726
727727
728
728
729729
730730
731731
......
734734
735735
736736
737
737
738738
739739
740
740
741741
742742
743743
......
747747
748748
749749
750
750
751751
752752
753753
......
755755
756756
757757
758
759
760
761
762
758
759
760
761
762
763763
764764
765765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788788
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* Source License Version 2.0 (the "License").You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* INTEL CORPORATION PROPRIETARY INFORMATION
*INTEL CORPORATION PROPRIETARY INFORMATION
*
* This software is supplied under the terms of a license agreement or
* nondisclosure agreement with Intel Corporation and may not be copied
* nor disclosed except in accordance with the terms of that agreement.
*This software is supplied under the terms of a licenseagreement or
*nondisclosure agreement with Intel Corporation and may not be copied
*nor disclosed except in accordance with the terms of that agreement.
*
* Copyright 1988, 1989 by Intel Corporation
*Copyright 1988, 1989 by Intel Corporation
*/
/*
* Reworked again by Curtis Galloway (galloway@NeXT.com)
*/
#include "boot.h"
#include "bootstruct.h"
#include "fake_efi.h"
bool gEnableCDROMRescan;
bool gScanSingleDrive;
int bvCount = 0;
intbvCount = 0;
//intmenucount = 0;
int gDeviceCount = 0;
intgDeviceCount = 0;
BVRef bvr;
BVRef menuBVR;
BVRef bvChain;
bool useGUI;
BVRefbvr;
BVRefmenuBVR;
BVRefbvChain;
booluseGUI;
//static void selectBiosDevice(void);
static unsigned long Adler32(unsigned char *buffer, long length);
{
extern char _DATA__bss__begin, _DATA__bss__end;
extern char _DATA__common__begin, _DATA__common__end;
bzero(&_DATA__bss__begin, (&_DATA__bss__end - &_DATA__bss__begin));
bzero(&_DATA__common__begin, (&_DATA__common__end - &_DATA__common__begin));
}
}
//==========================================================================
//Initializes the runtime. Right now this means zeroing the BSS and initializing malloc.
//Initializes the runtime.Right now this means zeroing the BSS and initializing malloc.
//
void initialize_runtime(void)
{
// Notify modules that the kernel has been decoded
execute_hook("DecodedKernel", (void*)binary, NULL, NULL, NULL);
setupFakeEfi();
setupFakeEfi();
// Load boot drivers from the specifed root path.
//if (!gHaveKernelCache)
LoadDrivers("/");
//if (!gHaveKernelCache)
LoadDrivers("/");
execute_hook("DriversLoaded", (void*)binary, NULL, NULL, NULL);
execute_hook("DriversLoaded", (void*)binary, NULL, NULL, NULL);
clearActivityIndicator();
if (gErrors) {
printf("Pausing %d seconds...\n", kBootErrorTimeout);
sleep(kBootErrorTimeout);
}
md0Ramdisk();
verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");
usb_loop();
if (checkOSVersion("10.7"))
{
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL);// Notify modules that the kernel is about to be started
}
else
{
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL);// Notify modules that the kernel is about to be started
}
// Notify modules that the kernel is about to be started
if (checkOSVersion("10.7"))
{
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL);
}
else
{
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL);
}
// If we were in text mode, switch to graphics mode.
// This will draw the boot graphics unless we are in
// verbose mode.
if(gVerboseMode)
if (gVerboseMode)
setVideoMode( GRAPHICS_MODE, 0 );
else
drawBootGraphics();
finalizeBootStruct();
if (checkOSVersion("10.7")) {
// Jump to kernel's entry point. There's no going back now.
if (checkOSVersion("10.7")) {
// Masking out so that Lion doesn't doublefault
outb(0x21, 0xff);/* Maskout all interrupts Pic1 */
outb(0xa1, 0xff);/* Maskout all interrupts Pic2 */
// Jump to kernel's entry point. There's no going back now.
startprog( kernelEntry, bootArgs );
}
else {
// Jump to kernel's entry point. There's no going back now.
startprog( kernelEntry, bootArgsPreLion );
}
// Not reached
return 0;
}
// from a block device, or by the network booter.
//
// arguments:
// biosdev - Value passed from boot1/NBP to specify the device
// that the booter was loaded from.
// biosdev - Value passed from boot1/NBP to specify the device
// that the booter was loaded from.
//
// If biosdev is kBIOSDevNetwork, then this function will return if
// booting was unsuccessful. This allows the PXE firmware to try the
// next boot device on its list.
void common_boot(int biosdev)
{
int status;
char *bootFile;
unsigned long adler32;
bool quiet;
bool firstRun = true;
bool instantMenu;
bool rescanPrompt;
unsigned int allowBVFlags = kBVFlagSystemVolume | kBVFlagForeignBoot;
unsigned int denyBVFlags = kBVFlagEFISystem;
// Set reminder to unload the PXE base code. Neglect to unload
// the base code will result in a hang or kernel panic.
gUnloadPXEOnExit = true;
// Record the device that the booter was loaded from.
gBIOSDev = biosdev & kBIOSDevMask;
// Initialize boot info structure.
initKernBootStruct();
intstatus;
char *bootFile;
unsigned longadler32;
bool quiet;
bool firstRun = true;
bool instantMenu;
bool rescanPrompt;
unsigned intallowBVFlags = kBVFlagSystemVolume | kBVFlagForeignBoot;
unsigned intdenyBVFlags = kBVFlagEFISystem;
// Set reminder to unload the PXE base code. Neglect to unload
// the base code will result in a hang or kernel panic.
gUnloadPXEOnExit = true;
// Record the device that the booter was loaded from.
gBIOSDev = biosdev & kBIOSDevMask;
// Initialize boot info structure.
initKernBootStruct();
initBooterLog();
// Setup VGA text mode.
// Not sure if it is safe to call setVideoMode() before the
// config table has been loaded. Call video_mode() instead.
// Setup VGA text mode.
// Not sure if it is safe to call setVideoMode() before the
// config table has been loaded. Call video_mode() instead.
#if DEBUG
printf("before video_mode\n");
printf("before video_mode\n");
#endif
video_mode( 2 ); // 80x25 mono text mode.
video_mode( 2 ); // 80x25 mono text mode.
#if DEBUG
printf("after video_mode\n");
printf("after video_mode\n");
#endif
// Scan and record the system's hardware information.
scan_platform();
// First get info for boot volume.
scanBootVolumes(gBIOSDev, 0);
bvChain = getBVChainForBIOSDev(gBIOSDev);
setBootGlobals(bvChain);
// Load boot.plist config file
status = loadChameleonConfig(&bootInfo->chameleonConfig);
if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet) {
gBootMode |= kBootModeQuiet;
}
// Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
if (getBoolForKey(kInsantMenuKey, &instantMenu, &bootInfo->chameleonConfig) && instantMenu) {
firstRun = false;
}
// Loading preboot ramdisk if exists.
loadPrebootRAMDisk();
// Disable rescan option by default
gEnableCDROMRescan = false;
// Enable it with Rescan=y in system config
if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->chameleonConfig) && gEnableCDROMRescan) {
gEnableCDROMRescan = true;
}
// Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
rescanPrompt = false;
if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->chameleonConfig) && rescanPrompt && biosDevIsCDROM(gBIOSDev)) {
gEnableCDROMRescan = promptForRescanOption();
}
// Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->chameleonConfig) && gScanSingleDrive) {
gScanSingleDrive = true;
}
// Create a list of partitions on device(s).
if (gScanSingleDrive) {
scanBootVolumes(gBIOSDev, &bvCount);
} else {
scanDisks(gBIOSDev, &bvCount);
}
// Create a separated bvr chain using the specified filters.
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
gBootVolume = selectBootVolume(bvChain);
// Scan and record the system's hardware information.
scan_platform();
// First get info for boot volume.
scanBootVolumes(gBIOSDev, 0);
bvChain = getBVChainForBIOSDev(gBIOSDev);
setBootGlobals(bvChain);
// Load boot.plist config file
status = loadChameleonConfig(&bootInfo->chameleonConfig);
if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet) {
gBootMode |= kBootModeQuiet;
}
// Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
if (getBoolForKey(kInsantMenuKey, &instantMenu, &bootInfo->chameleonConfig) && instantMenu) {
firstRun = false;
}
// Loading preboot ramdisk if exists.
loadPrebootRAMDisk();
// Disable rescan option by default
gEnableCDROMRescan = false;
// Enable it with Rescan=y in system config
if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->chameleonConfig) && gEnableCDROMRescan) {
gEnableCDROMRescan = true;
}
// Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
rescanPrompt = false;
if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->chameleonConfig)
&& rescanPrompt && biosDevIsCDROM(gBIOSDev))
{
gEnableCDROMRescan = promptForRescanOption();
}
// Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->chameleonConfig) && gScanSingleDrive) {
gScanSingleDrive = true;
}
// Create a list of partitions on device(s).
if (gScanSingleDrive) {
scanBootVolumes(gBIOSDev, &bvCount);
} else {
scanDisks(gBIOSDev, &bvCount);
}
// Create a separated bvr chain using the specified filters.
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
gBootVolume = selectBootVolume(bvChain);
// Intialize module system
init_module_system();
#if DEBUG
printf(" Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags);
printf(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags);
getchar();
printf(" Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags);
printf(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags);
getchar();
#endif
useGUI = true;
// Override useGUI default
getBoolForKey(kGUIKey, &useGUI, &bootInfo->chameleonConfig);
// initGUI() returned with an error, disabling GUI.
useGUI = false;
}
setBootGlobals(bvChain);
// Parse args, load and start kernel.
while (1) {
const char *val;
int len;
int trycache;
long flags, cachetime, kerneltime, exttime, sleeptime, time;
int ret = -1;
void *binary = (void *)kLoadAddr;
bool tryresume;
bool tryresumedefault;
bool forceresume;
setBootGlobals(bvChain);
// Parse args, load and start kernel.
while (1) {
const char *val;
int len;
int trycache;
long flags, cachetime, kerneltime, exttime, sleeptime, time;
int ret = -1;
void *binary = (void *)kLoadAddr;
bool tryresume;
bool tryresumedefault;
bool forceresume;
bool usecache = false;//true;
// additional variable for testing alternate kernel image locations on boot helper partitions.
char bootFileSpec[512];
// Initialize globals.
sysConfigValid = false;
gErrors = false;
status = getBootOptions(firstRun);
firstRun = false;
if (status == -1) continue;
// additional variable for testing alternate kernel image locations on boot helper partitions.
char bootFileSpec[512];
status = processBootOptions();
// Status==1 means to chainboot
if ( status == 1 ) break;
// Status==-1 means that the config file couldn't be loaded or that gBootVolume is NULL
if ( status == -1 )
{
// gBootVolume == NULL usually means the user hit escape.
if(gBootVolume == NULL)
{
freeFilteredBVChain(bvChain);
if (gEnableCDROMRescan)
rescanBIOSDevice(gBIOSDev);
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
setBootGlobals(bvChain);
setupDeviceList(&bootInfo->themeConfig);
}
continue;
}
// Initialize globals.
// Other status (e.g. 0) means that we should proceed with boot.
sysConfigValid = false;
gErrors = false;
status = getBootOptions(firstRun);
firstRun = false;
if (status == -1) continue;
status = processBootOptions();
// Status==1 means to chainboot
if ( status ==1 ) break;
// Status==-1 means that the config file couldn't be loaded or that gBootVolume is NULL
if ( status == -1 )
{
// gBootVolume == NULL usually means the user hit escape.
if (gBootVolume == NULL)
{
freeFilteredBVChain(bvChain);
if (gEnableCDROMRescan)
rescanBIOSDevice(gBIOSDev);
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
setBootGlobals(bvChain);
setupDeviceList(&bootInfo->themeConfig);
}
continue;
}
// Other status (e.g. 0) means that we should proceed with boot.
// Turn off any GUI elements
if( bootArgs->Video.v_display == GRAPHICS_MODE )
if ( bootArgs->Video.v_display == GRAPHICS_MODE )
{
gui.devicelist.draw = false;
gui.bootprompt.draw = false;
// Find out which version mac os we're booting.
getOSVersion();
if (platformCPUFeature(CPU_FEATURE_EM64T)) {
archCpuType = CPU_TYPE_X86_64;
} else {
archCpuType = CPU_TYPE_I386;
}
if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
// Notify modules that we are attempting to boot
execute_hook("PreBoot", NULL, NULL, NULL, NULL);
if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) {
tryresume = true;
tryresumedefault = true;
} else {
tryresumedefault = false;
}
if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) {
forceresume = false;
}
// Do this first to be sure that root volume is mounted
ret = GetFileInfo(0, val, &flags, &sleeptime);
if ((bvr = getBootVolumeRef(val, &tmp)) == NULL)
break;
break;
if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
#if DEBUG
printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",bvr->modTime-sleeptime);
#endif
#if DEBUG
printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",
bvr->modTime-sleeptime);
#endif
break;
}
HibernateBoot((char *)val);
break;
}
getBoolForKey(kUseKernelCache, &usecache, &bootInfo->chameleonConfig);
if(usecache) {
if (usecache) {
if (getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig)) {
if(val[0] == '\\')
{
len--;
val++;
}
strlcpy(gBootKernelCacheFile, val, len+1);
if (val[0] == '\\')
{
len--;
val++;
}
strlcpy(gBootKernelCacheFile, val, len+1);
}
else {
//Lion
else if (checkOSVersion("10.6")) {
sprintf(gBootKernelCacheFile, "kernelcache_%s", (archCpuType == CPU_TYPE_I386) ? "i386" : "x86_64");
int lnam = sizeof(gBootKernelCacheFile) + 9; //with adler32
//Slice - TODO ???
// e.g. kernelcache_i386.E102928C.qSs0 = "unsaved" cache file.
//
// See kext_tools-180.2.1/kextcache_main.c:
// "Source directory has changed since starting; "
// "not saving cache file %s."
// or
// "Source kernel has changed since starting; "
// "not saving cache file %s."
char* name;
long prev_time = 0;
while(readdir(cacheDir, (const char**)&name, &flags, &time) >= 0)
{
if(((flags & kFileTypeMask) != kFileTypeDirectory) && time > prev_time && strstr(name, gBootKernelCacheFile) && (name[lnam] != '.'))
if (((flags & kFileTypeMask) != kFileTypeDirectory) && time > prev_time
&& strstr(name, gBootKernelCacheFile) && (name[lnam] != '.'))
{
sprintf(gBootKernelCacheFile, "%s%s", kDefaultCachePathSnow, name);
prev_time = time;
}
}
}
// Check for cache file.
trycache = (usecache &&
// Check for cache file.
trycache = (usecache &&
((gBootMode & kBootModeSafe) == 0) &&
!gOverrideKernel &&
(gBootFileType == kBlockDeviceType) &&
(gMKextName[0] == '\0') &&
(gBootKernelCacheFile[0] != '\0'));
!gOverrideKernel &&
(gBootFileType == kBlockDeviceType) &&
(gMKextName[0] == '\0') &&
(gBootKernelCacheFile[0] != '\0'));
verbose("Loading Darwin %s\n", gMacOSVersion);
if (trycache) do {
ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime);
if(ret != 0) kerneltime = 0;
else if ((flags & kFileTypeMask) != kFileTypeFlat) {
trycache = 0;
break;
}
if (trycache) do {
ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime);
if (ret != 0) kerneltime = 0;
else if ((flags & kFileTypeMask) != kFileTypeFlat) {
trycache = 0;
break;
}
ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)
|| (cachetime < kerneltime)) {
trycache = 0;
break;
}
ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime);
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)
&& (cachetime < exttime)) {
trycache = 0;
break;
}
if (ret == 0 && kerneltime > exttime) {
exttime = kerneltime;
}
if (ret == 0 && cachetime != (exttime + 1)) {
trycache = 0;
break;
}
} while (0);
ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)
|| (cachetime < kerneltime)) {
trycache = 0;
break;
}
ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime);
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)
&& (cachetime < exttime)) {
trycache = 0;
break;
}
if (ret == 0 && kerneltime > exttime) {
exttime = kerneltime;
}
if (ret == 0 && cachetime != (exttime + 1)) {
trycache = 0;
break;
}
} while (0);
do {
if (trycache) {
bootFile = gBootKernelCacheFile;
do {
if (trycache) {
bootFile = gBootKernelCacheFile;
verbose("Loading kernel cache %s\n", bootFile);
if (checkOSVersion("10.7")) {
ret = LoadThinFatFile(bootFile, &binary);
if (checkOSVersion("10.7")) {
ret = LoadThinFatFile(bootFile, &binary);
}
else {
ret = LoadFile(bootFile);
ret = LoadFile(bootFile);
binary = (void *)kLoadAddr;
}
if (ret >= 0)
break;
if (ret >= 0)
break;
verbose("Kernel cache did not load %s\n ", bootFile);
}
if (checkOSVersion("10.7")) {
bootFile = gBootKernelCacheFile;
}
else {
sprintf(bootFile, "\%s", bootInfo->bootFile);
}
// Try to load kernel image from alternate locations on boot helper partitions.
sprintf(bootFileSpec, "com.apple.boot.P%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.R%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.S%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
// No alternate location found, using the original kernel image path.
strcpy(bootFileSpec, bootInfo->bootFile);
}
}
}
if (checkOSVersion("10.7"))
{
//Lion, dont load kernel if haz cache
if (!trycache)
{
verbose("Loading kernel %s\n", bootFileSpec);
ret = LoadThinFatFile(bootFileSpec, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
{
archCpuType = CPU_TYPE_I386;
ret = LoadThinFatFile(bootFileSpec, &binary);
}
}
}
if (checkOSVersion("10.7")) {
bootFile = gBootKernelCacheFile;
}
else {
sprintf(bootFile, "\%s", bootInfo->bootFile);
}
// Try to load kernel image from alternate locations on boot helper partitions.
sprintf(bootFileSpec, "com.apple.boot.P%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.R%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.S%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
// No alternate location found, using the original kernel image path.
strcpy(bootFileSpec, bootInfo->bootFile);
}
}
}
if (checkOSVersion("10.7"))
{
//Lion, dont load kernel if haz cache
if (!trycache)
{
verbose("Loading kernel %s\n", bootFileSpec);
ret = LoadThinFatFile(bootFileSpec, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
{
archCpuType = CPU_TYPE_I386;
ret = LoadThinFatFile(bootFileSpec, &binary);
}
}
else ret = 1;
}
}
else
{
//Snow Leopard or older
verbose("Loading kernel %s\n", bootFileSpec);
ret = LoadThinFatFile(bootFileSpec, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
{
archCpuType = CPU_TYPE_I386;
ret = LoadThinFatFile(bootFileSpec, &binary);
}
}
} while (0);
clearActivityIndicator();
{
//Snow Leopard or older
verbose("Loading kernel %s\n", bootFileSpec);
ret = LoadThinFatFile(bootFileSpec, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
{
archCpuType = CPU_TYPE_I386;
ret = LoadThinFatFile(bootFileSpec, &binary);
}
}
} while (0);
clearActivityIndicator();
#if DEBUG
printf("Pausing...");
sleep(8);
printf("Pausing...");
sleep(8);
#endif
if (ret <= 0) {
if (ret <= 0) {
printf("Can't find %s\n", bootFile);
sleep(1);
if (gBootFileType == kNetworkDeviceType) {
// Return control back to PXE. Don't unload PXE base code.
gUnloadPXEOnExit = false;
break;
}
} else {
/* Won't return if successful. */
ret = ExecKernel(binary);
}
}
// chainboot
if (status==1) {
if (getVideoMode() == GRAPHICS_MODE) {// if we are already in graphics-mode,
setVideoMode(VGA_TEXT_MODE, 0);// switch back to text mode
if (gBootFileType == kNetworkDeviceType) {
// Return control back to PXE. Don't unload PXE base code.
gUnloadPXEOnExit = false;
break;
}
} else {
/* Won't return if successful. */
ret = ExecKernel(binary);
}
}
}
if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
// chainboot
if (status==1) {
// if we are already in graphics-mode,
if (getVideoMode() == GRAPHICS_MODE) {
setVideoMode(VGA_TEXT_MODE, 0); // switch back to text mode.
}
}
if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
nbpUnloadBaseCode();
}
}
}
/*!
Selects a new BIOS device, taking care to update the global state appropriately.
Selects a new BIOS device, taking care to update the global state appropriately.
*/
/*
static void selectBiosDevice(void)
{
struct DiskBVMap *oldMap = diskResetBootVolumes(gBIOSDev);
CacheReset();
diskFreeMap(oldMap);
oldMap = NULL;
int dev = selectAlternateBootDevice(gBIOSDev);
BVRef bvchain = scanBootVolumes(dev, 0);
BVRef bootVol = selectBootVolume(bvchain);
gBootVolume = bootVol;
setRootVolume(bootVol);
gBIOSDev = dev;
struct DiskBVMap *oldMap = diskResetBootVolumes(gBIOSDev);
CacheReset();
diskFreeMap(oldMap);
oldMap = NULL;
int dev = selectAlternateBootDevice(gBIOSDev);
BVRef bvchain = scanBootVolumes(dev, 0);
BVRef bootVol = selectBootVolume(bvchain);
gBootVolume = bootVol;
setRootVolume(bootVol);
gBIOSDev = dev;
}
*/
bool checkOSVersion(const char * version)
{
return ((gMacOSVersion[0] == version[0]) && (gMacOSVersion[1] == version[1]) && (gMacOSVersion[2] == version[2]) && (gMacOSVersion[3] == version[3]));
return ((gMacOSVersion[0] == version[0]) && (gMacOSVersion[1] == version[1])
&& (gMacOSVersion[2] == version[2]) && (gMacOSVersion[3] == version[3]));
}
bool getOSVersion()
config_file_t systemVersion;
const char *val;
int len;
if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion))
{
valid = true;
{
valid = true;
}
if (valid)
{
if (getValueForKey(kProductVersion, &val, &len, &systemVersion))
if(getValueForKey(kProductVersion, &val, &len, &systemVersion))
{
// getValueForKey uses const char for val
// so copy it and trim
else
valid = false;
}
return valid;
}
#define NMAX 5000
// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
#define DO1(buf,i){s1 += buf[i]; s2 += s1;}
#define DO2(buf,i)DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i)DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i)DO4(buf,i); DO4(buf,i+4);
#define DO16(buf)DO8(buf,0); DO8(buf,8);
unsigned long Adler32(unsigned char *buf, long len)
{
unsigned long s1 = 1; // adler & 0xffff;
unsigned long s2 = 0; // (adler >> 16) & 0xffff;
unsigned long result;
int k;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
result = (s2 << 16) | s1;
return OSSwapHostToBigInt32(result);
unsigned long s1 = 1; // adler & 0xffff;
unsigned long s2 = 0; // (adler >> 16) & 0xffff;
unsigned long result;
int k;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
result = (s2 << 16) | s1;
return OSSwapHostToBigInt32(result);
}

Archive Download the corresponding diff file

Revision: 1374