Annotation of sys/arch/sparc64/stand/ofwboot/boot.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: boot.c,v 1.14 2007/05/29 00:03:13 deraadt Exp $ */
2: /* $NetBSD: boot.c,v 1.3 2001/05/31 08:55:19 mrg Exp $ */
3: /*
4: * Copyright (c) 1997, 1999 Eduardo E. Horvath. All rights reserved.
5: * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
6: * Copyright (C) 1995, 1996 Wolfgang Solfrank.
7: * Copyright (C) 1995, 1996 TooLs GmbH.
8: * All rights reserved.
9: *
10: * ELF support derived from NetBSD/alpha's boot loader, written
11: * by Christopher G. Demetriou.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. All advertising materials mentioning features or use of this software
22: * must display the following acknowledgement:
23: * This product includes software developed by TooLs GmbH.
24: * 4. The name of TooLs GmbH may not be used to endorse or promote products
25: * derived from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
28: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: /*
40: * First try for the boot code
41: *
42: * Input syntax is:
43: * [promdev[{:|,}partition]]/[filename] [flags]
44: */
45:
46: #define ELFSIZE 64
47:
48: #include <lib/libsa/stand.h>
49:
50: #include <sys/param.h>
51: #include <sys/exec.h>
52: #include <sys/exec_elf.h>
53: #include <sys/reboot.h>
54: #include <sys/disklabel.h>
55: #include <machine/boot_flag.h>
56:
57: #include <machine/cpu.h>
58:
59: #include "ofdev.h"
60: #include "openfirm.h"
61:
62: #define MEG (1024*1024)
63:
64: /*
65: * Boot device is derived from ROM provided information, or if there is none,
66: * this list is used in sequence, to find a kernel.
67: */
68: char *kernels[] = {
69: "bsd",
70: NULL
71: };
72:
73: char bootdev[128];
74: char bootfile[128];
75: int boothowto;
76: int debug;
77:
78:
79: #ifdef SPARC_BOOT_ELF
80: int elf64_exec(int, Elf64_Ehdr *, u_int64_t *, void **, void **);
81: #endif
82:
83: #if 0
84: static void
85: prom2boot(dev)
86: char *dev;
87: {
88: char *cp, *lp = 0;
89: int handle;
90: char devtype[16];
91:
92: for (cp = dev; *cp; cp++)
93: if (*cp == ':')
94: lp = cp;
95: if (!lp)
96: lp = cp;
97: *lp = 0;
98: }
99: #endif
100:
101: /*
102: * parse:
103: * [kernel-name] [-options]
104: * leave kernel-name in passed-in string
105: * put options into *howtop
106: * return -1 iff syntax error (no - before options)
107: */
108:
109: static int
110: parseargs(str, howtop)
111: char *str;
112: int *howtop;
113: {
114: char *cp;
115: int i;
116:
117: *howtop = 0;
118: cp = str;
119: while (*cp == ' ')
120: ++cp;
121: if (*cp != '-') {
122: while (*cp && *cp != ' ')
123: *str++ = *cp++;
124: while (*cp == ' ')
125: ++cp;
126: }
127: *str = 0;
128: switch(*cp) {
129: default:
130: printf ("boot options string <%s> must start with -\n", cp);
131: return -1;
132: case 0:
133: return 0;
134: case '-':
135: break;
136: }
137:
138: ++cp;
139: while (*cp) {
140: BOOT_FLAG(*cp, *howtop);
141: /* handle specialties */
142: switch (*cp++) {
143: case 'd':
144: if (!debug) debug = 1;
145: break;
146: case 'D':
147: debug = 2;
148: break;
149: }
150: }
151: return 0;
152: }
153:
154:
155: static void
156: chain(pentry, args, ssym, esym)
157: u_int64_t pentry;
158: char *args;
159: void *ssym;
160: void *esym;
161: {
162: extern char end[];
163: void (*entry)();
164: int l, machine_tag;
165: long newargs[3];
166:
167: entry = (void *)(long)pentry;
168:
169: freeall();
170: /*
171: * When we come in args consists of a pointer to the boot
172: * string. We need to fix it so it takes into account
173: * other params such as romp.
174: */
175:
176: /*
177: * Stash pointer to end of symbol table after the argument
178: * strings.
179: */
180: l = strlen(args) + 1;
181: bcopy(&esym, args + l, sizeof(esym));
182: l += sizeof(esym);
183:
184: /*
185: * Tell the kernel we're an OpenFirmware system.
186: */
187: #define SPARC_MACHINE_OPENFIRMWARE 0x44444230
188: machine_tag = SPARC_MACHINE_OPENFIRMWARE;
189: bcopy(&machine_tag, args + l, sizeof(machine_tag));
190: l += sizeof(machine_tag);
191:
192: /*
193: * Since we don't need the boot string (we can get it from /chosen)
194: * we won't pass it in. Just pass in esym and magic #
195: */
196: newargs[0] = SPARC_MACHINE_OPENFIRMWARE;
197: newargs[1] = (long)esym;
198: newargs[2] = (long)ssym;
199: args = (char *)newargs;
200: l = sizeof(newargs);
201:
202: #ifdef DEBUG
203: printf("chain: calling OF_chain(%x, %x, %x, %x, %x)\n",
204: (void *)RELOC, end - (char *)RELOC, entry, args, l);
205: #endif
206: /* if -D is set then pause in the PROM. */
207: if (debug > 1) OF_enter();
208: OF_chain((void *)RELOC, ((end - (char *)RELOC)+NBPG)%NBPG, entry, args, l);
209: panic("chain");
210: }
211:
212: int
213: loadfile(fd, args)
214: int fd;
215: char *args;
216: {
217: union {
218: #ifdef SPARC_BOOT_ELF
219: Elf64_Ehdr elf64;
220: #endif
221: } hdr;
222: int rval;
223: u_int64_t entry = 0;
224: void *ssym;
225: void *esym;
226:
227: ssym = NULL;
228: esym = NULL;
229:
230: /* Load the header. */
231: #ifdef DEBUG
232: printf("loadfile: reading header\n");
233: #endif
234: if ((rval = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
235: if (rval == -1)
236: printf("read header: %s\n", strerror(errno));
237: else
238: printf("read header: short read (only %d of %d)\n",
239: rval, sizeof(hdr));
240: rval = 1;
241: goto err;
242: }
243:
244: /* Determine file type, load kernel. */
245: #ifdef SPARC_BOOT_ELF
246: if (bcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
247: hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
248: rval = elf64_exec(fd, &hdr.elf64, &entry, &ssym, &esym);
249: } else
250: #endif
251: {
252: rval = 1;
253: printf("unknown executable format\n");
254: }
255:
256: if (rval)
257: goto err;
258:
259: printf(" start=0x%lx\n", (unsigned long)entry);
260:
261: close(fd);
262:
263: chain(entry, args, ssym, esym);
264: /* NOTREACHED */
265:
266: err:
267: close(fd);
268: return (rval);
269: }
270:
271: #ifdef SPARC_BOOT_ELF
272: #include "elfXX_exec.c"
273: #endif /* SPARC_BOOT_ELF */
274:
275: int
276: main()
277: {
278: extern char version[];
279: int chosen;
280: char bootline[512]; /* Should check size? */
281: char *cp;
282: int i, fd;
283: char **bootlp;
284: char *just_bootline[2];
285:
286: printf(">> OpenBSD BOOT %s\n", version);
287:
288: /*
289: * Get the boot arguments from Openfirmware
290: */
291: if ((chosen = OF_finddevice("/chosen")) == -1 ||
292: OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 ||
293: OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
294: printf("Invalid Openfirmware environment\n");
295: exit();
296: }
297:
298: /*
299: * case 1: boot net -a
300: * -> gets loop
301: * case 2: boot net kernel [options]
302: * -> boot kernel, gets loop
303: * case 3: boot net [options]
304: * -> iterate boot list, gets loop
305: */
306:
307: bootlp = kernels;
308: if (parseargs(bootline, &boothowto) == -1 ||
309: (boothowto & RB_ASKNAME)) {
310: bootlp = 0;
311: } else if (*bootline) {
312: just_bootline[0] = bootline;
313: just_bootline[1] = 0;
314: bootlp = just_bootline;
315: }
316: for (;;) {
317: if (bootlp) {
318: cp = *bootlp++;
319: if (!cp) {
320: printf("\n");
321: bootlp = 0;
322: kernels[0] = 0; /* no more iteration */
323: } else if (cp != bootline) {
324: printf("Trying %s...\n", cp);
325: strlcpy(bootline, cp, sizeof bootline);
326: }
327: }
328: if (!bootlp) {
329: printf("Boot: ");
330: gets(bootline);
331: if (parseargs(bootline, &boothowto) == -1)
332: continue;
333: if (!*bootline) {
334: bootlp = kernels;
335: continue;
336: }
337: if (strcmp(bootline, "exit") == 0 ||
338: strcmp(bootline, "halt") == 0) {
339: _rtt();
340: }
341: }
342: if ((fd = open(bootline, 0)) < 0) {
343: printf("open %s: %s\n", opened_name, strerror(errno));
344: continue;
345: }
346: #ifdef __notyet__
347: OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
348: cp = bootline;
349: #else
350: strlcpy(bootline, opened_name, sizeof bootline);
351: cp = bootline + strlen(bootline);
352: *cp++ = ' ';
353: #endif
354: *cp = '-';
355: if (boothowto & RB_ASKNAME)
356: *++cp = 'a';
357: if (boothowto & RB_SINGLE)
358: *++cp = 's';
359: if (boothowto & RB_KDB)
360: *++cp = 'd';
361: if (*cp == '-')
362: *--cp = 0;
363: else
364: *++cp = 0;
365: #ifdef __notyet__
366: OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
367: #endif
368: /* XXX void, for now */
369: #ifdef DEBUG
370: if (debug)
371: printf("main: Calling loadfile(fd, %s)\n", bootline);
372: #endif
373: (void)loadfile(fd, bootline);
374: }
375: return 0;
376: }
CVSweb