boot.c revision 1.1 1 /* $NetBSD: boot.c,v 1.1 2003/06/25 17:24:22 cdi Exp $ */
2
3 /*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jonathan Stone, Michael Hitch, Simon Burge and Wayne Knowles.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Copyright (c) 1992, 1993
41 * The Regents of the University of California. All rights reserved.
42 *
43 * This code is derived from software contributed to Berkeley by
44 * Ralph Campbell.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. All advertising materials mentioning features or use of this software
55 * must display the following acknowledgement:
56 * This product includes software developed by the University of
57 * California, Berkeley and its contributors.
58 * 4. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
61 *
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 * SUCH DAMAGE.
73 *
74 * @(#)boot.c 8.1 (Berkeley) 6/10/93
75 */
76
77 #include <machine/cpu.h>
78 #include <machine/leds.h>
79 #include <machine/vmparam.h>
80
81 #include <lib/libsa/stand.h>
82 #include <lib/libsa/loadfile.h>
83 #include <lib/libkern/libkern.h>
84
85 #include <sys/param.h>
86 #include <sys/exec.h>
87 #include <sys/exec_elf.h>
88
89 #include "boot.h"
90 #include "cons.h"
91 #include "common.h"
92
93 char *kernelnames[] = {
94 "netbsd",
95 "netbsd.gz",
96 "onetbsd",
97 "onetbsd.gz",
98 "netbsd.bak",
99 "netbsd.bak.gz",
100 "netbsd.old",
101 "netbsd.old.gz",
102 "netbsd.cobalt",
103 "netbsd.cobalt.gz",
104 "netbsd.elf",
105 "netbsd.elf.gz",
106 NULL
107 };
108
109 extern long end;
110 static char *bootstring;
111
112 static int patch_bootstring (char *bootspec);
113 static int get_bsdbootname (char **dev, char **name, char **kname);
114 static int prominit (unsigned int memsize);
115 static int print_banner (unsigned int memsize);
116
117 void start(void);
118 int cpu_reboot(void);
119 int main(unsigned int memsize);
120
121 /*
122 * Perform CPU reboot.
123 */
124 int
125 cpu_reboot()
126 {
127 printf("rebooting...\n\n");
128
129 *(volatile char *)MIPS_PHYS_TO_KSEG1(LED_ADDR) = LED_RESET;
130 printf("WARNING: reboot failed!\n");
131
132 for (;;);
133 }
134
135 /*
136 * Substitute root value with NetBSD root partition name.
137 */
138 int
139 patch_bootstring(bootspec)
140 char *bootspec;
141 {
142 char *sp = bootstring;
143 u_int8_t unit, part;
144 int dev, error;
145 char *file;
146
147 DPRINTF(("patch_bootstring: %s\n", bootspec));
148
149 /* get boot parameters */
150 if (devparse(bootspec, &dev, &unit, &part, (const char **)&file) != 0)
151 unit = part = 0;
152
153 DPRINTF(("patch_bootstring: %d, %d\n", unit, part));
154
155 /* take out the 'root=xxx' parameter */
156 if ( (sp = strstr(bootstring, "root=")) != NULL) {
157 const char *end;
158
159 end = strchr(sp, ' ');
160
161 /* strip off leading spaces */
162 for (--sp; (sp > bootstring) && (*sp == ' '); --sp)
163 ;
164
165 if (end != NULL)
166 strcpy(++sp, end);
167 else
168 *++sp = '\0';
169 }
170
171 DPRINTF(("patch_bootstring: [%s]\n", bootstring));
172
173 #define DEVNAMESIZE (MAXDEVNAME + sizeof(" root=/dev/hd") + sizeof("0a"))
174 /* bsd notation -> linux notation (wd0a -> hda1) */
175 if (strlen(bootstring) <= (511 - DEVNAMESIZE)) {
176 int len;
177
178 strcat(bootstring, " root=/dev/hd");
179
180 len = strlen(bootstring);
181 bootstring[len++] = unit + 'a';
182 bootstring[len++] = part + '1';
183 bootstring[len++] = '\0';
184 }
185
186 DPRINTF(("patch_bootstring: -> %s\n", bootstring));
187 return (0);
188 }
189
190 /*
191 * Extract NetBSD boot specification
192 */
193 int
194 get_bsdbootname(dev, name, kname)
195 char **dev;
196 char **name;
197 char **kname;
198 {
199 char *spec;
200
201 *dev = NULL;
202 *name = NULL;
203 *kname = NULL;
204
205 if ( (spec = strstr(bootstring, "nbsd=")) != NULL) {
206 int len;
207 char *ptr = strchr(spec, ' ');
208
209 spec += 5; /* skip 'nbsd=' */
210 len = (ptr == NULL) ? strlen(spec) : ptr - spec;
211
212 if (len > 0) {
213 char *devname = alloc(len + 1);
214 if (devname != NULL) {
215 memcpy(devname, spec, len);
216 devname[len] = '\0';
217
218 if ( (ptr = memchr(devname,':',len)) != NULL) {
219 /* wdXX:kernel */
220 *ptr = '\0';
221 *dev = devname;
222
223 if (*++ptr)
224 *kname = ptr;
225
226 devname = alloc(len + 1);
227 if (devname != NULL) {
228 memcpy(devname, spec, len);
229 devname[len] = '\0';
230 }
231 }
232
233 *name = devname;
234 return (0);
235 }
236 }
237 }
238
239 return (1);
240 }
241
242 /*
243 * Get the bootstring from PROM.
244 */
245 int
246 prominit(memsize)
247 unsigned int memsize;
248 {
249 bootstring = (char *)(memsize - 512);
250 bootstring[511] = '\0';
251 }
252
253 /*
254 * Print boot message.
255 */
256 int
257 print_banner(memsize)
258 unsigned int memsize;
259 {
260 printf("\n");
261 printf(">> %s " NETBSD_VERS " Bootloader, Revision %s [@%p]\n",
262 bootprog_name, bootprog_rev,
263 (unsigned long)&start & ~PAGE_MASK);
264 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
265 printf(">> Memory:\t\t%u k\n", (memsize - MIPS_KSEG0_START) / 1024);
266 printf(">> PROM boot string:\t%s\n", bootstring);
267 }
268
269 /*
270 * Entry point.
271 * Parse PROM boot string, load the kernel and jump into it
272 */
273 int
274 main(memsize)
275 unsigned int memsize;
276 {
277 char *name, **namep, *dev, *kernel, *spec;
278 char bootpath[PATH_MAX];
279 int win;
280 u_long marks[MARK_MAX];
281 void (*entry) __P((unsigned int));
282
283 int addr, speed;
284
285 prominit(memsize);
286 cninit(&addr, &speed);
287
288 print_banner(memsize);
289
290 memset(marks, 0, sizeof marks);
291 get_bsdbootname(&dev, &name, &kernel);
292
293 if (kernel != NULL) {
294 DPRINTF(("kernel: %s\n", kernel));
295 patch_bootstring(name);
296 win = (loadfile(name, marks, LOAD_KERNEL) == 0);
297 } else {
298 win = 0;
299 DPRINTF(("kernel: NULL\n"));
300 for (namep = kernelnames, win = 0;
301 (*namep != NULL) && !win;
302 namep++) {
303 kernel = *namep;
304
305 bootpath[0] = '\0';
306
307 strcpy(bootpath, (dev != NULL) ? dev : "wd0a");
308 strcat(bootpath, ":");
309 strcat(bootpath, kernel);
310
311 printf("Loading: %s\n", bootpath);
312 patch_bootstring(bootpath);
313 win = (loadfile(bootpath, marks, LOAD_ALL) != -1);
314 }
315 }
316
317 if (win) {
318 entry = (void *) marks[MARK_ENTRY];
319
320 printf("Starting at 0x%x\n\n", (u_int)entry);
321 (*entry)(memsize);
322 }
323
324 (void)printf("Boot failed! Rebooting...\n");
325 return (0);
326 }
327