Root/
Source at commit 1407 created 12 years 10 months ago. By meklort, Revert drivers.c so that kexts are only loaded when OSBundleRequired is set and that value is not safe mode. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. The rights granted to you under the License␊ |
10 | * may not be used to create, or enable the creation or redistribution of,␊ |
11 | * unlawful or unlicensed copies of an Apple operating system, or to␊ |
12 | * circumvent, violate, or enable the circumvention or violation of, any␊ |
13 | * terms of an Apple operating system software license agreement.␊ |
14 | * ␊ |
15 | * Please obtain a copy of the License at␊ |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file.␊ |
17 | * ␊ |
18 | * The Original Code and all software distributed under the License are␊ |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
23 | * Please see the License for the specific language governing rights and␊ |
24 | * limitations under the License.␊ |
25 | * ␊ |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@␊ |
27 | */␊ |
28 | ␊ |
29 | /*␊ |
30 | * main.c - Main functions for BootX.␊ |
31 | *␊ |
32 | * Copyright (c) 1998-2004 Apple Computer, Inc.␊ |
33 | *␊ |
34 | * DRI: Josh de Cesare␊ |
35 | */␊ |
36 | ␊ |
37 | ␊ |
38 | #include <sl.h>␊ |
39 | #include <stdio.h>␊ |
40 | #include <string.h>␊ |
41 | ␊ |
42 | extern void␉malloc_init(char * start, int size, int nodes, void (*malloc_error)(char *, size_t, const char *, int));␊ |
43 | extern void init_module_system();␊ |
44 | extern int␉execute_hook(const char* name, void*, void*, void*, void*);␊ |
45 | ␊ |
46 | static void Start(void *unused1, void *unused2, ClientInterfacePtr ciPtr);␊ |
47 | static void Main(ClientInterfacePtr ciPtr);␊ |
48 | static long InitEverything(ClientInterfacePtr ciPtr);␊ |
49 | static long InitMemoryMap(void);␊ |
50 | static long GetOFVersion(void);␊ |
51 | static void malloc_error(char *addr, size_t size, const char *file, int line);␊ |
52 | ␊ |
53 | const unsigned long StartTVector[2] = {(unsigned long)Start, 0};␊ |
54 | ␊ |
55 | ␊ |
56 | char gStackBaseAddr[0x8000];␊ |
57 | ␊ |
58 | long gOFVersion = 0;␊ |
59 | ␊ |
60 | char *gKeyMap;␊ |
61 | ␊ |
62 | long gRootAddrCells;␊ |
63 | long gRootSizeCells;␊ |
64 | ␊ |
65 | CICell gChosenPH;␊ |
66 | CICell gMemoryMapPH;␊ |
67 | CICell gStdOutPH;␊ |
68 | ␊ |
69 | CICell gMMUIH;␊ |
70 | CICell gMemoryIH;␊ |
71 | CICell gStdOutIH;␊ |
72 | CICell gKeyboardIH;␊ |
73 | ␊ |
74 | ␊ |
75 | // Private Functions␊ |
76 | ␊ |
77 | static void malloc_error(char *addr, size_t size, const char *file, int line)␊ |
78 | {␊ |
79 | ␉printf("\nMemory allocation error! Addr=0x%x, Size=0x%x, File=%s, Line=%d\n", (unsigned)addr, (unsigned)size, file, line);␊ |
80 | ␉while(1);␊ |
81 | }␊ |
82 | ␊ |
83 | ␊ |
84 | static void Start(void *unused1, void *unused2, ClientInterfacePtr ciPtr)␊ |
85 | {␊ |
86 | ␉long newSP;␊ |
87 | ␉␊ |
88 | ␉// Move the Stack to a chunk of the BSS␊ |
89 | ␉newSP = (long)gStackBaseAddr + sizeof(gStackBaseAddr) - 0x100;␊ |
90 | ␉__asm__ volatile("mr r1, %0" : : "r" (newSP));␊ |
91 | ␉␊ |
92 | ␉Main(ciPtr);␊ |
93 | }␊ |
94 | ␊ |
95 | static void Main(ClientInterfacePtr ciPtr)␊ |
96 | {␊ |
97 | ␉int loopCount = 0;␊ |
98 | ␉long ret;␊ |
99 | ␉␊ |
100 | ␉ret = InitEverything(ciPtr);␊ |
101 | ␉if (ret != 0) Exit();␊ |
102 | ␉␊ |
103 | ␉// Intialize module system ␊ |
104 | ␉init_module_system();␊ |
105 | ␊ |
106 | ␉execute_hook("Initialize", (void*)loopCount++, (void*)ciPtr, 0, 0);␉// Main work loop␊ |
107 | ␊ |
108 | ␉while(1)␊ |
109 | {␊ |
110 | execute_hook("WorkLoop", (void*)loopCount++, (void*)ciPtr, 0, 0);␉// Main work loop␊ |
111 | }␉␊ |
112 | ␉␊ |
113 | }␊ |
114 | static long InitEverything(ClientInterfacePtr ciPtr)␊ |
115 | {␊ |
116 | ␉long ret, size;␊ |
117 | ␉CICell keyboardPH;␊ |
118 | ␉char name[32];␊ |
119 | ␉␊ |
120 | ␉// Init the OF Client Interface.␊ |
121 | ␉ret = InitCI(ciPtr);␊ |
122 | ␉if (ret != 0) return -1;␊ |
123 | ␉␊ |
124 | ␉// Get the OF Version␊ |
125 | ␉gOFVersion = GetOFVersion();␊ |
126 | ␉if (gOFVersion == 0) return -1;␊ |
127 | ␉␊ |
128 | ␉// Get the address and size cells for the root.␊ |
129 | ␉GetProp(Peer(0), "#address-cells", (char *)&gRootAddrCells, 4);␊ |
130 | ␉GetProp(Peer(0), "#size-cells", (char *)&gRootSizeCells, 4);␊ |
131 | ␉if ((gRootAddrCells > 2) || (gRootAddrCells > 2)) return -1;␊ |
132 | ␉␊ |
133 | ␉// Init the SL Words package.␊ |
134 | ␉ret = InitSLWords();␊ |
135 | ␉if (ret != 0) return -1;␊ |
136 | ␉␊ |
137 | ␉␊ |
138 | ␉// Get the phandle for /chosen␊ |
139 | ␉gChosenPH = FindDevice("/chosen");␊ |
140 | ␉if (gChosenPH == -1) return -1;␊ |
141 | ␉␊ |
142 | ␉// Init the Memory Map.␊ |
143 | ␉ret = InitMemoryMap();␊ |
144 | ␉if (ret != 0) return -1;␊ |
145 | ␉␊ |
146 | ␉// Get IHandles for the MMU and Memory␊ |
147 | ␉size = GetProp(gChosenPH, "mmu", (char *)&gMMUIH, 4);␊ |
148 | ␉if (size != 4) {␊ |
149 | ␉␉printf("Failed to get the IH for the MMU.\n");␊ |
150 | ␉␉return -1;␊ |
151 | ␉}␊ |
152 | ␉size = GetProp(gChosenPH, "memory", (char *)&gMemoryIH, 4);␊ |
153 | ␉if (size != 4) {␊ |
154 | ␉␉printf("Failed to get the IH for the Memory.\n");␊ |
155 | ␉␉return -1;␊ |
156 | ␉}␊ |
157 | ␉␉␊ |
158 | ␉// Get stdout's IH, so that the boot display can be found.␊ |
159 | ␉ret = GetProp(gChosenPH, "stdout", (char *)&gStdOutIH, 4);␊ |
160 | ␉if (ret == 4) gStdOutPH = InstanceToPackage(gStdOutIH);␊ |
161 | ␉else gStdOutPH = gStdOutIH = 0;␊ |
162 | ␉␊ |
163 | ␉// Try to find the keyboard using chosen␊ |
164 | ␉ret = GetProp(gChosenPH, "stdin", (char *)&gKeyboardIH, 4);␊ |
165 | ␉if (ret != 4) gKeyboardIH = 0;␊ |
166 | ␉else {␊ |
167 | ␉␉keyboardPH = InstanceToPackage(gKeyboardIH);␊ |
168 | ␉␉ret = GetProp(keyboardPH, "name", name, 31);␊ |
169 | ␉␉if (ret != -1) {␊ |
170 | ␉␉␉name[ret] = '\0';␊ |
171 | ␉␉␉if (strcmp(name, "keyboard") && strcmp(name, "kbd")) gKeyboardIH = 0;␊ |
172 | ␉␉} else gKeyboardIH = 0;␊ |
173 | ␉}␊ |
174 | ␉␊ |
175 | ␉// Try to the find the keyboard using open if chosen did not work.␊ |
176 | ␉if (gKeyboardIH == 0) gKeyboardIH = Open("keyboard");␊ |
177 | ␉if (gKeyboardIH == 0) gKeyboardIH = Open("kbd");␊ |
178 | ␉␊ |
179 | ␉// Get the key map set up, and make it up to date.␊ |
180 | ␉gKeyMap = InitKeyMap(gKeyboardIH);␊ |
181 | ␉if (gKeyMap == NULL) return -1;␊ |
182 | ␉UpdateKeyMap();␊ |
183 | ␉␊ |
184 | ␉SetOutputLevel(kOutputLevelFull);␊ |
185 | ␉␊ |
186 | ␉// printf now works.␊ |
187 | ␉printf("\n\nMac OS X Loader\n");␊ |
188 | ␉␊ |
189 | ␉// Claim memory for malloc.␊ |
190 | ␉if (Claim(kMallocAddr, kMallocSize, 0) == 0) {␊ |
191 | ␉␉printf("Claim for malloc failed.\n");␊ |
192 | ␉␉return -1;␊ |
193 | ␉}␊ |
194 | ␉malloc_init((char *)kMallocAddr, kMallocSize, 768, malloc_error);␊ |
195 | ␉␊ |
196 | ␉␊ |
197 | ␉return 0;␊ |
198 | }␊ |
199 | ␊ |
200 | static long InitMemoryMap(void)␊ |
201 | {␊ |
202 | ␉long result;␊ |
203 | ␉␊ |
204 | ␉result = Interpret(0, 1,␊ |
205 | ␉␉␉␉␉ " dev /chosen"␊ |
206 | ␉␉␉␉␉ " new-device"␊ |
207 | ␉␉␉␉␉ " \" memory-map\" device-name"␊ |
208 | ␉␉␉␉␉ " active-package"␊ |
209 | ␉␉␉␉␉ " device-end"␊ |
210 | ␉␉␉␉␉ , &gMemoryMapPH);␊ |
211 | ␉␊ |
212 | ␉return result;␊ |
213 | }␊ |
214 | ␊ |
215 | ␊ |
216 | static long GetOFVersion(void)␊ |
217 | {␊ |
218 | ␉CICell ph;␊ |
219 | ␉char versStr[256], *tmpStr;␊ |
220 | ␉long vers, size;␊ |
221 | ␉␊ |
222 | ␉// Get the openprom package␊ |
223 | ␉ph = FindDevice("/openprom");␊ |
224 | ␉if (ph == -1) return 0;␊ |
225 | ␉␊ |
226 | ␉// Get it's model property␊ |
227 | ␉size = GetProp(ph, "model", versStr, 255);␊ |
228 | ␉if (size == -1) return -1;␊ |
229 | ␉versStr[size] = '\0';␊ |
230 | ␉␊ |
231 | ␉// Find the start of the number.␊ |
232 | ␉tmpStr = NULL;␊ |
233 | ␉if (!strncmp(versStr, "Open Firmware, ", 15)) {␊ |
234 | ␉␉tmpStr = versStr + 15;␊ |
235 | ␉} else if (!strncmp(versStr, "OpenFirmware ", 13)) {␊ |
236 | ␉␉tmpStr = versStr + 13;␊ |
237 | ␉} else return -1;␊ |
238 | ␉␊ |
239 | ␉// Clasify by each instance as needed...␊ |
240 | ␉switch (*tmpStr) {␊ |
241 | ␉␉case '1' :␊ |
242 | ␉␉␉vers = kOFVersion1x;␊ |
243 | ␉␉␉break;␊ |
244 | ␉␉␉␊ |
245 | ␉␉case '2' :␊ |
246 | ␉␉␉vers = kOFVersion2x;␊ |
247 | ␉␉␉break;␊ |
248 | ␉␉␉␊ |
249 | ␉␉case '3' :␊ |
250 | ␉␉␉vers = kOFVersion3x;␊ |
251 | ␉␉␉break;␊ |
252 | ␉␉␉␊ |
253 | ␉␉case '4' :␊ |
254 | ␉␉␉vers = kOFVersion4x;␊ |
255 | ␉␉␉break;␊ |
256 | ␉␉␉␊ |
257 | ␉␉default :␊ |
258 | ␉␉␉vers = 0;␊ |
259 | ␉␉␉break;␊ |
260 | ␉}␊ |
261 | ␉␊ |
262 | ␉return vers;␊ |
263 | } |