]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/sl.subproj/main.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * main.c - Main functions for BootX.
25 * Copyright (c) 1998-2000 Apple Computer, Inc.
33 static void Start(void *unused1
, void *unused2
, ClientInterfacePtr ciPtr
);
34 static void Main(ClientInterfacePtr ciPtr
);
35 static long InitEverything(ClientInterfacePtr ciPtr
);
36 static long DecodeKernel(void);
37 static long SetUpBootArgs(void);
38 static long CallKernel(void);
39 static void FailToBoot(long num
);
40 static long InitMemoryMap(void);
41 static long GetOFVersion(void);
42 static long TestForKey(long key
);
43 static long GetBootPaths(void);
45 const unsigned long StartTVector
[2] = {(unsigned long)Start
, 0};
47 char gStackBaseAddr
[0x8000];
49 char *gVectorSaveAddr
;
50 long gImageLastKernelAddr
= 0;
51 long gImageFirstBootXAddr
= kLoadAddr
;
52 long gKernelEntryPoint
;
57 long gSymbolTableAddr
;
58 long gSymbolTableSize
;
60 long gBootSourceNumber
= -1;
61 long gBootSourceNumberMax
;
64 char gBootDevice
[256];
70 long *gDeviceTreeMMTmp
= 0;
89 static void Start(void *unused1
, void *unused2
, ClientInterfacePtr ciPtr
)
93 // Move the Stack to a chunk of the BSS
94 newSP
= (long)gStackBaseAddr
+ sizeof(gStackBaseAddr
) - 0x100;
95 __asm__
volatile("mr r1, %0" : : "r" (newSP
));
101 static void Main(ClientInterfacePtr ciPtr
)
105 ret
= InitEverything(ciPtr
);
106 if (ret
!= 0) Exit();
108 // Get or infer the boot paths.
109 ret
= GetBootPaths();
110 if (ret
!= 0) FailToBoot(1);
115 ret
= LoadFile(gBootFile
);
116 if (ret
!= -1) break;
118 ret
= GetBootPaths();
119 if (ret
!= 0) FailToBoot(2);
122 ret
= DecodeKernel();
123 if (ret
!= 0) FailToBoot(4);
125 ret
= LoadDrivers(gRootDir
);
126 if (ret
!= 0) FailToBoot(5);
129 ret
= LoadDisplayDrivers();
130 if (ret
!= 0) FailToBoot(6);
133 ret
= SetUpBootArgs();
134 if (ret
!= 0) FailToBoot(7);
142 static long InitEverything(ClientInterfacePtr ciPtr
)
144 long ret
, mem_base
, mem_base2
, size
;
148 char defaultBootDevice
[256];
151 // Init the OF Client Interface.
153 if (ret
!= 0) return -1;
155 // Get the OF Version
156 gOFVersion
= GetOFVersion();
157 if (gOFVersion
== 0) return -1;
159 // Init the SL Words package.
160 ret
= InitSLWords(gOFVersion
);
161 if (ret
!= 0) return -1;
163 // Get the phandle for /options
164 gOptionsPH
= FindDevice("/options");
165 if (gOptionsPH
== -1) return -1;
167 // Get the phandle for /chosen
168 gChosenPH
= FindDevice("/chosen");
169 if (gChosenPH
== -1) return -1;
171 // Init the Memory Map.
172 ret
= InitMemoryMap();
173 if (ret
!= 0) return -1;
175 // Get IHandles for the MMU and Memory
176 size
= GetProp(gChosenPH
, "mmu", (char *)&gMMUIH
, 4);
178 printf("Failed to get the IH for the MMU.\n");
181 size
= GetProp(gChosenPH
, "memory", (char *)&gMemoryIH
, 4);
183 printf("Failed to get the IH for the Memory.\n");
187 // Get stdout's IH, so that the boot display can be found.
188 ret
= GetProp(gChosenPH
, "stdout", (char *)&gStdOutIH
, 4);
189 if (ret
== 4) gStdOutPH
= InstanceToPackage(gStdOutIH
);
190 else gStdOutPH
= gStdOutIH
= 0;
192 // Try to find the keyboard using chosen
193 ret
= GetProp(gChosenPH
, "stdin", (char *)&gKeyboardIH
, 4);
194 if (ret
!= 4) gKeyboardIH
= 0;
196 keyboardPH
= InstanceToPackage(gKeyboardIH
);
197 ret
= GetProp(keyboardPH
, "name", name
, 31);
200 if (strcmp(name
, "keyboard") && strcmp(name
, "kbd")) gKeyboardIH
= 0;
201 } else gKeyboardIH
= 0;
204 // Try to the find the keyboard using open if chosen did not work.
205 if (gKeyboardIH
== 0) gKeyboardIH
= Open("keyboard");
206 if (gKeyboardIH
== 0) gKeyboardIH
= Open("kbd");
208 // Get the key map set up, and make it up to date.
209 gKeyMap
= InitKeyMap(gKeyboardIH
);
210 if (gKeyMap
== NULL
) return -1;
214 // On OF 3.x, if the Option key was pressed,
215 // set the default boot device and reboot.
216 if (gOFVersion
>= kOFVersion3x
) {
217 if (TestForKey(kOptKey
)) {
218 size
= GetProp(gOptionsPH
, "default-boot-device", defaultBootDevice
,255);
220 Interpret_0_0("set-default boot-device");
222 defaultBootDevice
[size
] = '\0';
223 SetProp(gOptionsPH
, "boot-device", defaultBootDevice
, size
);
224 SetProp(gOptionsPH
, "boot-file", 0, 0);
226 Interpret_0_0("reset-all");
232 // 'cmd-s' or 'cmd-v' is pressed set outputLevel to kOutputLevelFull
233 if (TestForKey(kCommandKey
) && (TestForKey('s') || TestForKey('v')))
234 SetOutputLevel(kOutputLevelFull
);
235 else SetOutputLevel(kOutputLevelOff
);
237 SetOutputLevel(kOutputLevelFull
);
241 printf("\n\nMac OS X Loader\n");
243 mem_base
= Claim(kMallocAddr
, kMallocSize
, 0);
245 printf("Claim for malloc failed.\n");
248 malloc_init((char *)mem_base
, kMallocSize
);
252 // Claim the memory for the Load Addr
253 mem_base
= Claim(kLoadAddr
, kLoadSize
, 0);
255 printf("Claim for Load Area failed.\n");
259 // Claim the memory for the Image Addr
260 if (gOFVersion
>= kOFVersion3x
) {
261 mem_base
= Claim(kImageAddr
, kImageSize
, 0);
263 printf("Claim for Image Area failed.\n");
267 // Claim the 1:1 mapped chunks first.
268 mem_base
= Claim(kImageAddr0
, kImageSize0
, 0);
269 mem_base2
= Claim(kImageAddr2
, kImageSize2
, 0);
270 if ((mem_base
== 0) || (mem_base2
== 0)) {
271 printf("Claim for Image Area failed.\n");
275 // Unmap the old xcoff stack.
276 CallMethod_2_0(gMMUIH
, "unmap", 0x00380000, 0x00080000);
278 // Grap the physical memory then the logical.
279 CallMethod_3_1(gMemoryIH
, "claim",
280 kImageAddr1Phys
, kImageSize1
, 0, &mem_base
);
281 CallMethod_3_1(gMMUIH
, "claim",
282 kImageAddr1
, kImageSize1
, 0, &mem_base2
);
283 if ((mem_base
== 0) || (mem_base2
== 0)) {
284 printf("Claim for Image Area failed.\n");
288 // Map them together.
289 CallMethod_4_0(gMMUIH
, "map",
290 kImageAddr1Phys
, kImageAddr1
, kImageSize1
, 0);
293 bzero((char *)kImageAddr
, kImageSize
);
295 // Malloc some space for the Vector Save area.
296 gVectorSaveAddr
= malloc(kVectorSize
);
297 if (gVectorSaveAddr
== 0) {
298 printf("Malloc for Vector Save Area failed.\n");
302 // Find all the displays and set them up.
303 ret
= InitDisplays();
305 printf("InitDisplays failed.\n");
313 static long DecodeKernel(void)
318 if (ret
== -1) ret
= DecodeElf();
324 static long SetUpBootArgs(void)
328 long secure
= 0, sym
= 0, graphicsBoot
= 1;
329 long ret
, cnt
, mem_size
, size
, dash
;
330 long aKey
, sKey
, vKey
, yKey
, shiftKey
, keyPos
;
331 char ofBootArgs
[128], *ofArgs
, tc
, keyStr
[8], securityMode
[33];
333 // Save file system cache statistics.
334 SetProp(gChosenPH
, "BootXCacheHits", (char *)&gCacheHits
, 4);
335 SetProp(gChosenPH
, "BootXCacheMisses", (char *)&gCacheMisses
, 4);
336 SetProp(gChosenPH
, "BootXCacheEvicts", (char *)&gCacheEvicts
, 4);
338 // Allocate some memory for the BootArgs.
339 gBootArgsSize
= sizeof(boot_args
);
340 gBootArgsAddr
= AllocateKernelMemory(gBootArgsSize
);
342 // Add the BootArgs to the memory-map.
343 AllocateMemoryRange("BootArgs", gBootArgsAddr
, gBootArgsSize
);
345 args
= (boot_args_ptr
)gBootArgsAddr
;
347 args
->Revision
= kBootArgsRevision
;
348 args
->Version
= kBootArgsVersion
;
349 args
->machineType
= 0;
351 // Get the security-mode.
352 size
= GetProp(gOptionsPH
, "security-mode", securityMode
, 32);
354 securityMode
[size
] = '\0';
355 if (strcmp(securityMode
, "none")) secure
= 1;
358 // Check the Keyboard for 'a', 'cmd-s', 'cmd-v', 'y' and shift
361 aKey
= TestForKey('a');
362 sKey
= TestForKey(kCommandKey
) && TestForKey('s');
363 vKey
= TestForKey(kCommandKey
) && TestForKey('v');
364 yKey
= TestForKey('y');
371 shiftKey
= TestForKey(kShiftKey
);
373 // if 'cmd-s' or 'cmd-v' was pressed do a text boot.
374 if (sKey
|| vKey
) graphicsBoot
= 0;
376 // if 'y' key was pressed send the symbols;
379 // Create the command line.
380 if (gOFVersion
< kOFVersion3x
) {
382 size
= GetProp(gChosenPH
, "machargs", ofBootArgs
+ 1, 126);
384 size
= GetProp(gOptionsPH
, "boot-command", ofBootArgs
, 127);
385 if (size
== -1) ofBootArgs
[0] = '\0';
386 else ofBootArgs
[size
] = '\0';
387 // Look for " bootr" but skip the number.
388 if (!strncmp(ofBootArgs
+ 1, " bootr", 6)) {
389 strcpy(ofBootArgs
, ofBootArgs
+ 7);
390 } else ofBootArgs
[0] = '\0';
391 SetProp(gChosenPH
, "machargs", ofBootArgs
, strlen(ofBootArgs
) + 1);
392 } else ofBootArgs
[size
] = '\0';
393 // Force boot-command to start with 0 bootr.
394 sprintf(gTempStr
, "0 bootr%s", ofBootArgs
);
395 SetProp(gOptionsPH
, "boot-command", gTempStr
, strlen(gTempStr
));
397 size
= GetProp(gOptionsPH
, "boot-args", ofBootArgs
, 127);
398 if (size
== -1) ofBootArgs
[0] = '\0';
399 else ofBootArgs
[size
] = '\0';
402 if (ofBootArgs
[0] != '\0') {
403 // Look for special options and copy the rest.
406 while ((tc
= *ofArgs
) != '\0') {
409 // Check for entering a dash arg.
416 // Do special stuff if in a dash arg.
422 else if (tc
== 's') {
427 else if (tc
== 'v') {
432 else if (tc
== 'x') {
436 else if (tc
== 'y') {
442 // Check for exiting dash arg
443 if (isspace(tc
)) dash
= 0;
445 // Copy any non 'a', 's', 'v', 'x' or 'y'
449 // Not a dash arg so just copy it.
455 // Add any pressed keys (a, s, v, y, shift) to the command line
457 if (aKey
|| sKey
|| vKey
|| yKey
|| shiftKey
) {
458 keyStr
[keyPos
++] = '-';
460 if (aKey
) keyStr
[keyPos
++] = 'a';
461 if (sKey
) keyStr
[keyPos
++] = 's';
462 if (vKey
) keyStr
[keyPos
++] = 'v';
463 if (yKey
) keyStr
[keyPos
++] = 'y';
464 if (shiftKey
) keyStr
[keyPos
++] = 'x';
466 keyStr
[keyPos
++] = ' ';
468 keyStr
[keyPos
++] = '\0';
471 if (!sym
&& !yKey
) gSymbolTableAddr
= 0;
473 sprintf(args
->CommandLine
, "%s%s symtab=%d",
474 keyStr
, ofBootArgs
, gSymbolTableAddr
);
476 // Get the memory info
477 memoryPH
= FindDevice("/memory");
478 if (memoryPH
== -1) return -1;
479 size
= GetProp(memoryPH
, "reg", (char *)(args
->PhysicalDRAM
),
480 kMaxDRAMBanks
* sizeof(DRAMBank
));
481 if (size
== 0) return -1;
483 // This is a hack to make the memory look like its all
486 for (cnt
= 0; cnt
< kMaxDRAMBanks
; cnt
++) {
487 mem_size
+= args
->PhysicalDRAM
[cnt
].size
;
488 args
->PhysicalDRAM
[cnt
].base
= 0;
489 args
->PhysicalDRAM
[cnt
].size
= 0;
491 args
->PhysicalDRAM
[0].size
= mem_size
;
493 // Get the video info
494 GetMainScreenPH(&args
->Video
);
495 args
->Video
.v_display
= graphicsBoot
;
497 // Add the DeviceTree to the memory-map.
498 // The actuall address and size must be filled in later.
499 AllocateMemoryRange("DeviceTree", 0, 0);
501 ret
= FlattenDeviceTree();
502 if (ret
!= 0) return -1;
504 // Fill in the address and size of the device tree.
505 if (gDeviceTreeAddr
) {
506 gDeviceTreeMMTmp
[0] = gDeviceTreeAddr
;
507 gDeviceTreeMMTmp
[1] = gDeviceTreeSize
;
510 args
->deviceTreeP
= (void *)gDeviceTreeAddr
;
511 args
->deviceTreeLength
= gDeviceTreeSize
;
512 args
->topOfKernelData
= AllocateKernelMemory(0);
518 static long CallKernel(void)
524 printf("\nCall Kernel!\n");
527 __asm__
volatile("mtmsr %0" : : "r" (msr
));
528 __asm__
volatile("isync");
530 // Move the Execption Vectors
531 bcopy(gVectorSaveAddr
, 0x0, kVectorSize
);
532 for (cnt
= 0; cnt
< kVectorSize
; cnt
+= 0x20) {
533 __asm__
volatile("dcbf 0, %0" : : "r" (cnt
));
534 __asm__
volatile("icbi 0, %0" : : "r" (cnt
));
537 // Move the Image1 save area for OF 1.x / 2.x
538 if (gOFVersion
< kOFVersion3x
) {
539 bcopy((char *)kImageAddr1Phys
, (char *)kImageAddr1
, kImageSize1
);
540 for (cnt
= kImageAddr1
; cnt
< kImageSize1
; cnt
+= 0x20) {
541 __asm__
volatile("dcbf 0, %0" : : "r" (cnt
));
542 __asm__
volatile("icbi 0, %0" : : "r" (cnt
));
546 // Make sure everything get sync'd up.
547 __asm__
volatile("isync");
548 __asm__
volatile("sync");
549 __asm__
volatile("eieio");
551 (*(void (*)())gKernelEntryPoint
)(gBootArgsAddr
, kMacOSXSignature
);
557 static void FailToBoot(long num
)
560 DrawBrokenSystemFolder();
564 printf("FailToBoot: %d\n", num
);
565 Enter(); // For debugging
570 static long InitMemoryMap(void)
574 result
= Interpret_0_1(
577 " \" memory-map\" device-name"
586 static long GetOFVersion(void)
589 char versStr
[256], *tmpStr
;
592 // Get the openprom package
593 ph
= FindDevice("/openprom");
594 if (ph
== -1) return 0;
596 // Get it's model property
597 size
= GetProp(ph
, "model", versStr
, 255);
598 if (size
== -1) return -1;
599 versStr
[size
] = '\0';
601 // Find the start of the number.
603 if (!strncmp(versStr
, "Open Firmware, ", 15)) {
604 tmpStr
= versStr
+ 15;
605 } else if (!strncmp(versStr
, "OpenFirmware ", 13)) {
606 tmpStr
= versStr
+ 13;
609 // Clasify by each instance as needed...
632 static long TestForKey(long key
)
638 if (gOFVersion
< kOFVersion3x
) {
640 case 'a' : keyNum
= 7; break;
641 case 's' : keyNum
= 6; break;
642 case 'v' : keyNum
= 14; break;
643 case 'y' : keyNum
= 23; break;
644 case kCommandKey
: keyNum
= 48; break;
645 case kOptKey
: keyNum
= 61; break;
646 case kShiftKey
: keyNum
= 63; break;
647 case kControlKey
: keyNum
= 49; break;
648 default : keyNum
= -1; break;
652 case 'a' : keyNum
= 3; break;
653 case 's' : keyNum
= 17; break;
654 case 'v' : keyNum
= 30; break;
655 case 'y' : keyNum
= 27; break;
656 case kCommandKey
: keyNum
= 228; break;
657 case kOptKey
: keyNum
= 229; break;
658 case kShiftKey
: keyNum
= 230; break;
659 case kControlKey
: keyNum
= 231; break;
660 default : keyNum
= -1; break;
663 // Map the right modifier keys on to the left.
664 gKeyMap
[28] |= gKeyMap
[28] << 4;
667 if (keyNum
== -1) return 0;
670 tc
= gKeyMap
[keyNum
>> 3];
672 return (tc
& (1 << bp
)) != 0;
676 #define kBootpBootFileOffset (108)
678 static long GetBootPaths(void)
680 long ret
, cnt
, cnt2
, cnt3
, cnt4
, size
, partNum
, bootplen
, bsdplen
;
681 char *filePath
, *buffer
;
683 if (gBootSourceNumber
== -1) {
684 // Get the boot-device
685 size
= GetProp(gChosenPH
, "bootpath", gBootDevice
, 255);
686 gBootDevice
[size
] = '\0';
687 if (gBootDevice
[0] == '\0') {
688 size
= GetProp(gOptionsPH
, "boot-device", gBootDevice
, 255);
689 gBootDevice
[size
] = '\0';
691 gBootDeviceType
= GetDeviceType(gBootDevice
);
694 size
= GetProp(gChosenPH
, "bootargs", gBootFile
, 256);
695 gBootFile
[size
] = '\0';
697 if (gBootFile
[0] != '\0') {
698 gBootFileType
= GetDeviceType(gBootFile
);
699 gBootSourceNumberMax
= 0;
701 gBootSourceNumber
= 0;
702 gBootFileType
= gBootDeviceType
;
703 if (gBootFileType
== kNetworkDeviceType
) gBootSourceNumberMax
= 1;
704 else gBootSourceNumberMax
= 4;
707 if (gBootFileType
== kNetworkDeviceType
) {
708 SetProp(Peer(0), "net-boot", NULL
, 0);
712 if (gBootSourceNumber
>= gBootSourceNumberMax
) return -1;
714 if (gBootSourceNumberMax
!= 0) {
715 switch (gBootFileType
) {
716 case kNetworkDeviceType
:
717 // Find the end of the device spec.
719 while (gBootDevice
[cnt
] != ':') cnt
++;
721 // Copy the device spec with the ':'.
722 strncpy(gBootFile
, gBootDevice
, cnt
+ 1);
724 // Check for bootp-responce or bsdp-responce.
725 bootplen
= GetPropLen(gChosenPH
, "bootp-response");
726 bsdplen
= GetPropLen(gChosenPH
, "bsdp-response");
727 if ((bootplen
> 0) || (bsdplen
> 0)) {
729 buffer
= malloc(bootplen
);
730 GetProp(gChosenPH
, "bootp-response", buffer
, bootplen
);
732 buffer
= malloc(bsdplen
);
733 GetProp(gChosenPH
, "bsdp-response", buffer
, bsdplen
);
736 // Flip the slash's to back slash's while looking for the last one.
737 cnt
= cnt2
= kBootpBootFileOffset
;
738 while (buffer
[cnt
] != '\0') {
739 if (buffer
[cnt
] == '/') {
746 // Add a comma at the front.
747 buffer
[kBootpBootFileOffset
- 1] = ',';
749 // Append the the root dir to the device spec.
750 strncat(gBootFile
, buffer
+ kBootpBootFileOffset
- 1,
751 cnt2
- kBootpBootFileOffset
+ 1);
755 // Look for the start of the root dir path.
757 while (gBootDevice
[cnt3
] != ',') cnt3
++;
759 // Find the end of the path. Look for a comma or null.
761 while ((gBootDevice
[cnt2
] != '\0') && (gBootDevice
[cnt2
] != ',')) cnt2
++;
763 // Find the last back slash or comma in the path
765 while ((gBootDevice
[cnt4
] != ',') && (gBootDevice
[cnt4
] != '\\')) cnt4
--;
767 // Copy the IP addresses if needed.
768 if (gOFVersion
< kOFVersion3x
) {
769 strncat(gBootFile
, gBootDevice
+ cnt
+ 1, cnt3
- cnt
- 1);
772 // Add on the directory path
773 strncat(gBootFile
, gBootDevice
+ cnt3
, cnt4
- cnt3
+ 1);
776 // Add on the kernel name
777 strcat(gBootFile
, "mach.macosx");
780 strcat(gBootFile
, gBootDevice
+ cnt2
);
783 case kBlockDeviceType
:
784 // Find the first ':'.
786 while ((gBootDevice
[cnt
] != '\0') && (gBootDevice
[cnt
] != ':')) cnt
++;
787 if (gBootDevice
[cnt
] == '\0') return -1;
789 // Find the comma after the ':'.
791 while ((gBootDevice
[cnt2
] != '\0') && (gBootDevice
[cnt
] != ',')) cnt2
++;
793 // Get just the partition number
794 strncpy(gBootFile
, gBootDevice
+ cnt
+ 1, cnt2
- cnt
- 1);
795 partNum
= atoi(gBootFile
);
797 if (gBootSourceNumber
> 1) {
798 // Adjust the partition number to the root partition
799 if (gOFVersion
< kOFVersion3x
) {
806 // Construct the boot-file
807 strncpy(gBootFile
, gBootDevice
, cnt
+ 1);
808 sprintf(gBootFile
+ cnt
+ 1, "%d,%s\\mach_kernel",
809 partNum
, ((gBootSourceNumber
& 1) ? "" : "\\"));
813 printf("Failed to infer Boot Device Type.\n");
819 // Figure out the root dir.
820 ret
= ConvertFileSpec(gBootFile
, gRootDir
, &filePath
);
821 if (ret
== -1) return -1;
823 strcat(gRootDir
, ",");
825 // Add in any extra path to gRootDir.
827 while (filePath
[cnt
] != '\0') cnt
++;
830 for (cnt2
= cnt
- 1; cnt2
>= 0; cnt2
--) {
831 if (filePath
[cnt2
] == '\\') {
832 strncat(gRootDir
, filePath
, cnt2
+ 1);
838 SetProp(gChosenPH
, "rootpath", gBootFile
, strlen(gBootFile
) + 1);
847 long GetDeviceType(char *devSpec
)
853 ph
= FindDevice(devSpec
);
854 if (ph
== -1) return -1;
856 size
= GetProp(ph
, "device_type", deviceType
, 31);
857 if (size
!= -1) deviceType
[size
] = '\0';
858 else deviceType
[0] = '\0';
860 if (strcmp(deviceType
, "network") == 0) return kNetworkDeviceType
;
861 if (strcmp(deviceType
, "block") == 0) return kBlockDeviceType
;
863 return kUnknownDeviceType
;
867 long ConvertFileSpec(char *fileSpec
, char *devSpec
, char **filePath
)
871 // Find the first ':' in the fileSpec.
873 while ((fileSpec
[cnt
] != '\0') && (fileSpec
[cnt
] != ':')) cnt
++;
874 if (fileSpec
[cnt
] == '\0') return -1;
876 // Find the next ',' in the fileSpec.
877 while ((fileSpec
[cnt
] != '\0') && (fileSpec
[cnt
] != ',')) cnt
++;
879 // Copy the string to devSpec.
880 strncpy(devSpec
, fileSpec
, cnt
);
883 // If there is a filePath start it after the ',', otherwise NULL.
884 if (filePath
!= NULL
) {
885 if (fileSpec
[cnt
] != '\0') {
886 *filePath
= fileSpec
+ cnt
+ 1;
896 long MatchThis(CICell phandle
, char *string
)
899 char *name
, *model
, *compatible
;
901 ret
= GetPackageProperty(phandle
, "name", &name
, &length
);
902 if ((ret
== -1) || (length
== 0)) name
= NULL
;
904 ret
= GetPackageProperty(phandle
, "model", &model
, &length
);
905 if ((ret
== -1) || (length
== 0)) model
= NULL
;
907 ret
= GetPackageProperty(phandle
, "compatible", &compatible
, &length
);
908 if ((ret
== -1) || (length
== 0)) model
= NULL
;
910 if ((name
!= NULL
) && strcmp(name
, string
) == 0) return 0;
911 if ((model
!= NULL
) && strcmp(model
, string
) == 0) return 0;
913 if (compatible
!= NULL
) {
914 while (*compatible
!= '\0') {
915 if (strcmp(compatible
, string
) == 0) return 0;
917 compatible
+= strlen(compatible
) + 1;
925 void *AllocateBootXMemory(long size
)
927 long addr
= gImageFirstBootXAddr
- size
;
929 if (addr
< gImageLastKernelAddr
) return 0;
931 gImageFirstBootXAddr
= addr
;
937 long AllocateKernelMemory(long size
)
939 long addr
= gImageLastKernelAddr
;
941 gImageLastKernelAddr
+= (size
+ 0xFFF) & ~0xFFF;
943 if (gImageLastKernelAddr
> gImageFirstBootXAddr
)
950 long AllocateMemoryRange(char *rangeName
, long start
, long length
)
952 long result
, *buffer
;
954 buffer
= AllocateBootXMemory(2 * sizeof(long));
955 if (buffer
== 0) return -1;
960 result
= SetProp(gMemoryMapPH
, rangeName
, (char *)buffer
, 2 * sizeof(long));
961 if (result
== -1) return -1;
967 unsigned long Alder32(unsigned char *buffer
, long length
)
970 unsigned long result
, lowHalf
, highHalf
;
975 for (cnt
= 0; cnt
< length
; cnt
++) {
976 if ((cnt
% 5000) == 0) {
981 lowHalf
+= buffer
[cnt
];
988 result
= (highHalf
<< 16) | lowHalf
;