boot.c revision 1.5 1 #define DEBUG
2 /* $NetBSD: boot.c,v 1.5 2006/01/27 01:55:34 uwe Exp $ */
3
4 /*-
5 * Copyright (c) 1997 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
42 * Copyright (C) 1995, 1996 TooLs GmbH.
43 * All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 * must display the following acknowledgement:
55 * This product includes software developed by TooLs GmbH.
56 * 4. The name of TooLs GmbH may not be used to endorse or promote products
57 * derived from this software without specific prior written permission.
58 *
59 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
60 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
61 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
62 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
63 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
64 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
65 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
66 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
67 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
68 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69 */
70
71 /*
72 * First try for the boot code
73 *
74 * Input syntax is:
75 * [promdev[{:|,}partition]]/[filename] [flags]
76 */
77
78 #define ELFSIZE 32 /* We use 32-bit ELF. */
79
80 #include <sys/param.h>
81 #include <sys/exec.h>
82 #include <sys/exec_elf.h>
83 #include <sys/reboot.h>
84 #include <sys/disklabel.h>
85 #include <sys/boot_flag.h>
86
87 #include <lib/libsa/stand.h>
88 #include <lib/libsa/loadfile.h>
89 #include <lib/libkern/libkern.h>
90
91 #include <machine/cpu.h>
92
93 #include "cache.h"
94 #include "extern.h"
95 #include "ofdev.h"
96 #include "openfirm.h"
97
98 #ifdef DEBUG
99 # define DPRINTF printf
100 #else
101 # define DPRINTF while (/*CONSTCOND*/0) printf
102 #endif
103
104 char bootdev[128];
105 char bootfile[128];
106 int boothowto;
107 int debug;
108
109 #ifdef notyet
110 static int ofw_version = 0;
111 #endif
112 static const char *kernels[] = {
113 "/netbsd", "/netbsd.gz", "/netbsd.shark", NULL
114 };
115
116 static void
117 prom2boot(char *dev)
118 {
119 char *cp, *ocp;
120
121 ocp = dev;
122 cp = dev + strlen(dev) - 1;
123 for (; cp >= ocp; cp--) {
124 if (*cp == ':') {
125 *cp = '\0';
126 return;
127 }
128 }
129 }
130
131 static void
132 parseargs(char *str, int *howtop)
133 {
134 char *cp;
135
136 /* Allow user to drop back to the PROM. */
137 if (strcmp(str, "exit") == 0)
138 OF_exit();
139
140 *howtop = 0;
141
142 for (cp = str; *cp; cp++)
143 if (*cp == ' ' || *cp == '-')
144 goto found;
145
146 return;
147
148 found:
149 *cp++ = '\0';
150 while (*cp)
151 BOOT_FLAG(*cp++, *howtop);
152 }
153
154 static void
155 chain(void (*entry)(int (*)(void *), void *, u_int), char *args, void *ssym,
156 void *esym)
157 {
158 extern char end[];
159 u_int l, magic = 0x19730224;
160
161 freeall();
162
163 /*
164 * Stash pointer to start and end of symbol table after the argument
165 * strings.
166 */
167 l = strlen(args) + 1;
168 l = (l + 3) & ~3; /* align */
169 DPRINTF("magic @ %p\n", args + l);
170 memcpy(args + l, &magic, sizeof(magic));
171 l += sizeof(magic);
172 DPRINTF("ssym @ %p\n", args + l);
173 memcpy(args + l, &ssym, sizeof(ssym));
174 l += sizeof(ssym);
175 DPRINTF("esym @ %p\n", args + l);
176 memcpy(args + l, &esym, sizeof(esym));
177 l += sizeof(esym);
178 DPRINTF("args + l -> %p\n", args + l);
179
180 DPRINTF("Calling OF_chain(%p, %tx, %p, %p, %u)\n",
181 (void *)RELOC, end - (char *)RELOC, entry, args, l);
182 OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l);
183 panic("chain");
184 }
185
186 __dead void
187 _rtt(void)
188 {
189
190 OF_exit();
191 }
192
193 void
194 main(void)
195 {
196 extern char bootprog_name[], bootprog_rev[],
197 bootprog_maker[], bootprog_date[];
198 int chosen;
199 char bootline[512]; /* Should check size? */
200 char *cp, *startbuf, *endbuf;
201 u_long marks[MARK_MAX], size;
202 u_int32_t entry;
203 void *ssym, *esym;
204
205 printf("\n");
206 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
207 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
208
209 /*
210 * Get the boot arguments from Openfirmware
211 */
212 if ((chosen = OF_finddevice("/chosen")) == -1 ||
213 OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 ||
214 OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
215 printf("Invalid Openfirmware environment\n");
216 OF_exit();
217 }
218
219 prom2boot(bootdev);
220 parseargs(bootline, &boothowto);
221 DPRINTF("bootline=%s\n", bootline);
222
223 /*
224 * Per the ARM OpenFirmware bindings, the firmware must
225 * allocate and map at least 6MB of physical memory starting
226 * at VA 0xf0000000. We have been loaded at 0xf0000000,
227 * and the memory after us has been unmapped and freed.
228 * We expect to load the kernel at 0xf0100000, so we will
229 * allocate 5MB of virtual memory starting there, and
230 * unmap/free what we don't use.
231 */
232 startbuf = OF_claim((void *) 0xf0100000, (5 * 1024 * 1024), 0);
233 if (startbuf != (void *) 0xf0100000) {
234 printf("Unable to claim buffer for kernel\n");
235 OF_exit();
236 }
237 endbuf = startbuf + (5 * 1024 * 1024);
238
239 for (;;) {
240 int i;
241
242 if (boothowto & RB_ASKNAME) {
243 printf("Boot: ");
244 gets(bootline);
245 parseargs(bootline, &boothowto);
246 }
247
248 if (bootline[0]) {
249 kernels[0] = bootline;
250 kernels[1] = NULL;
251 }
252
253 for (i = 0; kernels[i]; i++) {
254 DPRINTF("Trying %s\n", kernels[i]);
255
256 marks[MARK_START] = 0xf0100000;
257 if (loadfile(kernels[i], marks, LOAD_KERNEL) >= 0)
258 goto loaded;
259 }
260
261 boothowto |= RB_ASKNAME;
262 }
263 loaded:
264 /*
265 * Okay, kernel is loaded, free the extra memory at the end.
266 * Round to the ARM OpenFirmare page size (4k).
267 */
268 cp = (char *) ((marks[MARK_END] + 0xfff) & ~0xfff);
269 size = (u_long) (endbuf - cp);
270 if (size)
271 OF_release(cp, size);
272
273 #ifdef __notyet__
274 OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
275 cp = bootline;
276 #else
277 strcpy(bootline, opened_name);
278 cp = bootline + strlen(bootline);
279 *cp++ = ' ';
280 #endif
281 *cp = '-';
282 if (boothowto & RB_ASKNAME)
283 *++cp = 'a';
284 if (boothowto & RB_SINGLE)
285 *++cp = 's';
286 if (boothowto & RB_KDB)
287 *++cp = 'd';
288 if (*cp == '-')
289 #ifdef __notyet__
290 *cp = 0;
291 #else
292 *--cp = 0;
293 #endif
294 else
295 *++cp = 0;
296 #ifdef __notyet__
297 OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
298 #endif
299
300 entry = marks[MARK_ENTRY];
301 ssym = (void *)marks[MARK_SYM];
302 esym = (void *)marks[MARK_END];
303
304 printf(" start=0x%x\n", entry);
305
306 if (cache_syncI != NULL) {
307 DPRINTF("Syncing I$...\n");
308 (*cache_syncI)();
309 }
310
311 chain((void *)entry, bootline, ssym, esym);
312
313 OF_exit();
314 }
315