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