boot.c revision 1.2 1 1.2 jdolecek /* $NetBSD: boot.c,v 1.2 2000/09/24 12:32:39 jdolecek Exp $ */
2 1.1 mrg #define DEBUG
3 1.1 mrg /*
4 1.1 mrg * Copyright (c) 1997, 1999 Eduardo E. Horvath. All rights reserved.
5 1.1 mrg * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
6 1.1 mrg * Copyright (C) 1995, 1996 Wolfgang Solfrank.
7 1.1 mrg * Copyright (C) 1995, 1996 TooLs GmbH.
8 1.1 mrg * All rights reserved.
9 1.1 mrg *
10 1.1 mrg * ELF support derived from NetBSD/alpha's boot loader, written
11 1.1 mrg * by Christopher G. Demetriou.
12 1.1 mrg *
13 1.1 mrg * Redistribution and use in source and binary forms, with or without
14 1.1 mrg * modification, are permitted provided that the following conditions
15 1.1 mrg * are met:
16 1.1 mrg * 1. Redistributions of source code must retain the above copyright
17 1.1 mrg * notice, this list of conditions and the following disclaimer.
18 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
19 1.1 mrg * notice, this list of conditions and the following disclaimer in the
20 1.1 mrg * documentation and/or other materials provided with the distribution.
21 1.1 mrg * 3. All advertising materials mentioning features or use of this software
22 1.1 mrg * must display the following acknowledgement:
23 1.1 mrg * This product includes software developed by TooLs GmbH.
24 1.1 mrg * 4. The name of TooLs GmbH may not be used to endorse or promote products
25 1.1 mrg * derived from this software without specific prior written permission.
26 1.1 mrg *
27 1.1 mrg * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
28 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 1.1 mrg * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 1.1 mrg * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 1.1 mrg * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33 1.1 mrg * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34 1.1 mrg * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35 1.1 mrg * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 1.1 mrg * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 1.1 mrg */
38 1.1 mrg
39 1.1 mrg /*
40 1.1 mrg * First try for the boot code
41 1.1 mrg *
42 1.1 mrg * Input syntax is:
43 1.1 mrg * [promdev[{:|,}partition]]/[filename] [flags]
44 1.1 mrg */
45 1.1 mrg
46 1.1 mrg #ifdef ELFSIZE
47 1.1 mrg #undef ELFSIZE /* We use both. */
48 1.1 mrg #endif
49 1.1 mrg
50 1.1 mrg #include <lib/libsa/stand.h>
51 1.1 mrg #include <lib/libkern/libkern.h>
52 1.1 mrg
53 1.1 mrg #include <sys/param.h>
54 1.1 mrg #include <sys/exec.h>
55 1.1 mrg #include <sys/exec_elf.h>
56 1.1 mrg #include <sys/reboot.h>
57 1.1 mrg #include <sys/disklabel.h>
58 1.2 jdolecek #include <sys/boot_flag.h>
59 1.1 mrg
60 1.1 mrg #include <machine/cpu.h>
61 1.1 mrg
62 1.1 mrg #include "ofdev.h"
63 1.1 mrg #include "openfirm.h"
64 1.1 mrg
65 1.1 mrg #define MEG (1024*1024)
66 1.1 mrg
67 1.1 mrg /*
68 1.1 mrg * Boot device is derived from ROM provided information, or if there is none,
69 1.1 mrg * this list is used in sequence, to find a kernel.
70 1.1 mrg */
71 1.1 mrg char *kernels[] = {
72 1.1 mrg "netbsd ",
73 1.1 mrg "netbsd.gz ",
74 1.1 mrg "netbsd.old ",
75 1.1 mrg "netbsd.old.gz ",
76 1.1 mrg "onetbsd ",
77 1.1 mrg "onetbsd.gz ",
78 1.1 mrg "vmunix ",
79 1.1 mrg #ifdef notyet
80 1.1 mrg "netbsd.pl ",
81 1.1 mrg "netbsd.pl.gz ",
82 1.1 mrg "netbsd.el ",
83 1.1 mrg "netbsd.el.gz ",
84 1.1 mrg #endif
85 1.1 mrg NULL
86 1.1 mrg };
87 1.1 mrg
88 1.1 mrg char *kernelname;
89 1.1 mrg char bootdev[128];
90 1.1 mrg char bootfile[128];
91 1.1 mrg int boothowto;
92 1.1 mrg int debug;
93 1.1 mrg
94 1.1 mrg
95 1.1 mrg #ifdef SPARC_BOOT_ELF
96 1.1 mrg int elf32_exec __P((int, Elf32_Ehdr *, u_int64_t *, void **, void **));
97 1.1 mrg int elf64_exec __P((int, Elf64_Ehdr *, u_int64_t *, void **, void **));
98 1.1 mrg #endif
99 1.1 mrg
100 1.1 mrg #ifdef SPARC_BOOT_AOUT
101 1.1 mrg int aout_exec __P((int, struct exec *, u_int64_t *, void **));
102 1.1 mrg #endif
103 1.1 mrg
104 1.1 mrg #if 0
105 1.1 mrg static void
106 1.1 mrg prom2boot(dev)
107 1.1 mrg char *dev;
108 1.1 mrg {
109 1.1 mrg char *cp, *lp = 0;
110 1.1 mrg int handle;
111 1.1 mrg char devtype[16];
112 1.1 mrg
113 1.1 mrg for (cp = dev; *cp; cp++)
114 1.1 mrg if (*cp == ':')
115 1.1 mrg lp = cp;
116 1.1 mrg if (!lp)
117 1.1 mrg lp = cp;
118 1.1 mrg *lp = 0;
119 1.1 mrg }
120 1.1 mrg #endif
121 1.1 mrg
122 1.1 mrg static void
123 1.1 mrg parseargs(str, howtop)
124 1.1 mrg char *str;
125 1.1 mrg int *howtop;
126 1.1 mrg {
127 1.1 mrg char *cp;
128 1.1 mrg int i;
129 1.1 mrg
130 1.1 mrg /* Allow user to drop back to the PROM. */
131 1.1 mrg if (strcmp(str, "exit") == 0)
132 1.1 mrg _rtt();
133 1.1 mrg
134 1.1 mrg /* Insert the kernel name if it is not there. */
135 1.1 mrg if (str[0] == 0 || str[0] == '-') {
136 1.1 mrg /* Move args down the string */
137 1.1 mrg i=0;
138 1.1 mrg for (cp = str + strlen(kernelname); str[i]; i++)
139 1.1 mrg cp[i] = str[i];
140 1.1 mrg /* Copy over kernelname */
141 1.1 mrg for (i = 0; kernelname[i]; i++)
142 1.1 mrg str[i] = kernelname[i];
143 1.1 mrg }
144 1.1 mrg *howtop = 0;
145 1.1 mrg for (cp = str; *cp; cp++)
146 1.1 mrg if (*cp == ' ' || *cp == '-')
147 1.1 mrg break;
148 1.1 mrg if (!*cp)
149 1.1 mrg return;
150 1.1 mrg
151 1.1 mrg *cp++ = 0;
152 1.1 mrg while (*cp) {
153 1.2 jdolecek BOOT_FLAG(*cp, *howtop);
154 1.2 jdolecek /* handle specialties */
155 1.1 mrg switch (*cp++) {
156 1.1 mrg case 'd':
157 1.1 mrg if (!debug) debug = 1;
158 1.1 mrg break;
159 1.1 mrg case 'D':
160 1.1 mrg debug = 2;
161 1.1 mrg break;
162 1.2 jdolecek default:
163 1.1 mrg break;
164 1.1 mrg }
165 1.1 mrg }
166 1.1 mrg }
167 1.1 mrg
168 1.1 mrg
169 1.1 mrg static void
170 1.1 mrg chain(pentry, args, ssym, esym)
171 1.1 mrg u_int64_t pentry;
172 1.1 mrg char *args;
173 1.1 mrg void *ssym;
174 1.1 mrg void *esym;
175 1.1 mrg {
176 1.1 mrg extern char end[];
177 1.1 mrg void (*entry)();
178 1.1 mrg int l, machine_tag;
179 1.1 mrg long newargs[3];
180 1.1 mrg
181 1.1 mrg entry = (void*)(long)pentry;
182 1.1 mrg
183 1.1 mrg freeall();
184 1.1 mrg /*
185 1.1 mrg * When we come in args consists of a pointer to the boot
186 1.1 mrg * string. We need to fix it so it takes into account
187 1.1 mrg * other params such as romp.
188 1.1 mrg */
189 1.1 mrg
190 1.1 mrg /*
191 1.1 mrg * Stash pointer to end of symbol table after the argument
192 1.1 mrg * strings.
193 1.1 mrg */
194 1.1 mrg l = strlen(args) + 1;
195 1.1 mrg bcopy(&esym, args + l, sizeof(esym));
196 1.1 mrg l += sizeof(esym);
197 1.1 mrg
198 1.1 mrg /*
199 1.1 mrg * Tell the kernel we're an OpenFirmware system.
200 1.1 mrg */
201 1.1 mrg #define SPARC_MACHINE_OPENFIRMWARE 0x44444230
202 1.1 mrg machine_tag = SPARC_MACHINE_OPENFIRMWARE;
203 1.1 mrg bcopy(&machine_tag, args + l, sizeof(machine_tag));
204 1.1 mrg l += sizeof(machine_tag);
205 1.1 mrg
206 1.1 mrg /*
207 1.1 mrg * Since we don't need the boot string (we can get it from /chosen)
208 1.1 mrg * we won't pass it in. Just pass in esym and magic #
209 1.1 mrg */
210 1.1 mrg newargs[0] = SPARC_MACHINE_OPENFIRMWARE;
211 1.1 mrg newargs[1] = (long)esym;
212 1.1 mrg newargs[2] = (long)ssym;
213 1.1 mrg args = (char *)newargs;
214 1.1 mrg l = sizeof(newargs);
215 1.1 mrg
216 1.1 mrg #ifdef DEBUG
217 1.1 mrg printf("chain: calling OF_chain(%x, %x, %x, %x, %x)\n",
218 1.1 mrg (void *)RELOC, end - (char *)RELOC, entry, args, l);
219 1.1 mrg #endif
220 1.1 mrg /* if -D is set then pause in the PROM. */
221 1.1 mrg if (debug > 1) OF_enter();
222 1.1 mrg OF_chain((void *)RELOC, ((end - (char *)RELOC)+NBPG)%NBPG, entry, args, l);
223 1.1 mrg panic("chain");
224 1.1 mrg }
225 1.1 mrg
226 1.1 mrg int
227 1.1 mrg loadfile(fd, args)
228 1.1 mrg int fd;
229 1.1 mrg char *args;
230 1.1 mrg {
231 1.1 mrg union {
232 1.1 mrg #ifdef SPARC_BOOT_AOUT
233 1.1 mrg struct exec aout;
234 1.1 mrg #endif
235 1.1 mrg #ifdef SPARC_BOOT_ELF
236 1.1 mrg Elf32_Ehdr elf32;
237 1.1 mrg Elf64_Ehdr elf64;
238 1.1 mrg #endif
239 1.1 mrg } hdr;
240 1.1 mrg int rval;
241 1.1 mrg u_int64_t entry = 0;
242 1.1 mrg void *ssym;
243 1.1 mrg void *esym;
244 1.1 mrg
245 1.1 mrg rval = 1;
246 1.1 mrg ssym = NULL;
247 1.1 mrg esym = NULL;
248 1.1 mrg
249 1.1 mrg /* Load the header. */
250 1.1 mrg #ifdef DEBUG
251 1.1 mrg printf("loadfile: reading header\n");
252 1.1 mrg #endif
253 1.1 mrg if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
254 1.1 mrg printf("read header: %s\n", strerror(errno));
255 1.1 mrg goto err;
256 1.1 mrg }
257 1.1 mrg
258 1.1 mrg /* Determine file type, load kernel. */
259 1.1 mrg #ifdef SPARC_BOOT_AOUT
260 1.1 mrg if (N_BADMAG(hdr.aout) == 0 && N_GETMID(hdr.aout) == MID_SPARC) {
261 1.1 mrg rval = aout_exec(fd, &hdr.aout, &entry, &esym);
262 1.1 mrg } else
263 1.1 mrg #endif
264 1.1 mrg #ifdef SPARC_BOOT_ELF
265 1.1 mrg if (bcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 &&
266 1.1 mrg hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
267 1.1 mrg rval = elf32_exec(fd, &hdr.elf32, &entry, &ssym, &esym);
268 1.1 mrg } else
269 1.1 mrg if (bcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
270 1.1 mrg hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
271 1.1 mrg rval = elf64_exec(fd, &hdr.elf64, &entry, &ssym, &esym);
272 1.1 mrg } else
273 1.1 mrg #endif
274 1.1 mrg {
275 1.1 mrg printf("unknown executable format\n");
276 1.1 mrg }
277 1.1 mrg
278 1.1 mrg if (rval)
279 1.1 mrg goto err;
280 1.1 mrg
281 1.1 mrg printf(" start=0x%lx\n", (unsigned long)entry);
282 1.1 mrg
283 1.1 mrg close(fd);
284 1.1 mrg
285 1.1 mrg /* XXX this should be replaced w/ a mountroothook. */
286 1.1 mrg if (floppyboot) {
287 1.1 mrg printf("Please insert root disk and press ENTER ");
288 1.1 mrg getchar();
289 1.1 mrg printf("\n");
290 1.1 mrg }
291 1.1 mrg
292 1.1 mrg chain(entry, args, ssym, esym);
293 1.1 mrg /* NOTREACHED */
294 1.1 mrg
295 1.1 mrg err:
296 1.1 mrg close(fd);
297 1.1 mrg return (rval);
298 1.1 mrg }
299 1.1 mrg
300 1.1 mrg #ifdef SPARC_BOOT_AOUT
301 1.1 mrg int
302 1.1 mrg aout_exec(fd, hdr, entryp, esymp)
303 1.1 mrg int fd;
304 1.1 mrg struct exec *hdr;
305 1.1 mrg u_int64_t *entryp;
306 1.1 mrg void **esymp;
307 1.1 mrg {
308 1.1 mrg void *addr;
309 1.1 mrg int n, *paddr;
310 1.1 mrg
311 1.1 mrg #ifdef DEBUG
312 1.1 mrg printf("auout_exec: ");
313 1.1 mrg #endif
314 1.1 mrg /* Display the load address (entry point) for a.out. */
315 1.1 mrg printf("Booting %s @ 0x%lx\n", opened_name, hdr->a_entry);
316 1.1 mrg addr = (void *)(hdr->a_entry);
317 1.1 mrg
318 1.1 mrg /*
319 1.1 mrg * Determine memory needed for kernel and allocate it from
320 1.1 mrg * the firmware.
321 1.1 mrg */
322 1.1 mrg n = hdr->a_text + hdr->a_data + hdr->a_bss + hdr->a_syms + sizeof(int);
323 1.1 mrg if ((paddr = OF_claim(addr, n, 0)) == (int *)-1)
324 1.1 mrg panic("cannot claim memory");
325 1.1 mrg
326 1.1 mrg /* Load text. */
327 1.1 mrg lseek(fd, N_TXTOFF(*hdr), SEEK_SET);
328 1.1 mrg printf("%lu", hdr->a_text);
329 1.1 mrg if (read(fd, paddr, hdr->a_text) != hdr->a_text) {
330 1.1 mrg printf("read text: %s\n", strerror(errno));
331 1.1 mrg return (1);
332 1.1 mrg }
333 1.1 mrg syncicache((void *)paddr, hdr->a_text);
334 1.1 mrg
335 1.1 mrg /* Load data. */
336 1.1 mrg printf("+%lu", hdr->a_data);
337 1.1 mrg if (read(fd, (void *)paddr + hdr->a_text, hdr->a_data) != hdr->a_data) {
338 1.1 mrg printf("read data: %s\n", strerror(errno));
339 1.1 mrg return (1);
340 1.1 mrg }
341 1.1 mrg
342 1.1 mrg /* Zero BSS. */
343 1.1 mrg printf("+%lu", hdr->a_bss);
344 1.1 mrg bzero((void *)paddr + hdr->a_text + hdr->a_data, hdr->a_bss);
345 1.1 mrg
346 1.1 mrg /* Symbols. */
347 1.1 mrg *esymp = paddr;
348 1.1 mrg paddr = (int *)((void *)paddr + hdr->a_text + hdr->a_data + hdr->a_bss);
349 1.1 mrg *paddr++ = hdr->a_syms;
350 1.1 mrg if (hdr->a_syms) {
351 1.1 mrg printf(" [%lu", hdr->a_syms);
352 1.1 mrg if (read(fd, paddr, hdr->a_syms) != hdr->a_syms) {
353 1.1 mrg printf("read symbols: %s\n", strerror(errno));
354 1.1 mrg return (1);
355 1.1 mrg }
356 1.1 mrg paddr = (int *)((void *)paddr + hdr->a_syms);
357 1.1 mrg if (read(fd, &n, sizeof(int)) != sizeof(int)) {
358 1.1 mrg printf("read symbols: %s\n", strerror(errno));
359 1.1 mrg return (1);
360 1.1 mrg }
361 1.1 mrg if (OF_claim((void *)paddr, n + sizeof(int), 0) == (void *)-1)
362 1.1 mrg panic("cannot claim memory");
363 1.1 mrg *paddr++ = n;
364 1.1 mrg if (read(fd, paddr, n - sizeof(int)) != n - sizeof(int)) {
365 1.1 mrg printf("read symbols: %s\n", strerror(errno));
366 1.1 mrg return (1);
367 1.1 mrg }
368 1.1 mrg printf("+%d]", n - sizeof(int));
369 1.1 mrg *esymp = paddr + (n - sizeof(int));
370 1.1 mrg }
371 1.1 mrg
372 1.1 mrg *entryp = hdr->a_entry;
373 1.1 mrg return (0);
374 1.1 mrg }
375 1.1 mrg #endif /* SPARC_BOOT_AOUT */
376 1.1 mrg
377 1.1 mrg #ifdef SPARC_BOOT_ELF
378 1.1 mrg #if 1
379 1.1 mrg /* New style */
380 1.1 mrg
381 1.1 mrg #ifdef ELFSIZE
382 1.1 mrg #undef ELFSIZE
383 1.1 mrg #endif
384 1.1 mrg
385 1.1 mrg #define ELFSIZE 32
386 1.1 mrg #include "elfXX_exec.c"
387 1.1 mrg
388 1.1 mrg #undef ELFSIZE
389 1.1 mrg #define ELFSIZE 64
390 1.1 mrg #include "elfXX_exec.c"
391 1.1 mrg
392 1.1 mrg #else
393 1.1 mrg /* Old style */
394 1.1 mrg int
395 1.1 mrg elf32_exec(fd, elf, entryp, ssymp, esymp)
396 1.1 mrg int fd;
397 1.1 mrg Elf32_Ehdr *elf;
398 1.1 mrg u_int64_t *entryp;
399 1.1 mrg void **ssymp;
400 1.1 mrg void **esymp;
401 1.1 mrg {
402 1.1 mrg Elf32_Shdr *shp;
403 1.1 mrg Elf32_Off off;
404 1.1 mrg void *addr;
405 1.1 mrg size_t size;
406 1.1 mrg int i, first = 1;
407 1.1 mrg long align;
408 1.1 mrg int n;
409 1.1 mrg
410 1.1 mrg /*
411 1.1 mrg * Don't display load address for ELF; it's encoded in
412 1.1 mrg * each section.
413 1.1 mrg */
414 1.1 mrg #ifdef DEBUG
415 1.1 mrg printf("elf_exec: ");
416 1.1 mrg #endif
417 1.1 mrg printf("Booting %s\n", opened_name);
418 1.1 mrg
419 1.1 mrg for (i = 0; i < elf->e_phnum; i++) {
420 1.1 mrg Elf32_Phdr phdr;
421 1.1 mrg (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET);
422 1.1 mrg if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
423 1.1 mrg printf("read phdr: %s\n", strerror(errno));
424 1.1 mrg return (1);
425 1.1 mrg }
426 1.1 mrg if (phdr.p_type != PT_LOAD ||
427 1.1 mrg (phdr.p_flags & (PF_W|PF_X)) == 0)
428 1.1 mrg continue;
429 1.1 mrg
430 1.1 mrg /* Read in segment. */
431 1.1 mrg printf("%s%lu@0x%lx", first ? "" : "+", phdr.p_filesz,
432 1.1 mrg (u_long)phdr.p_vaddr);
433 1.1 mrg (void)lseek(fd, phdr.p_offset, SEEK_SET);
434 1.1 mrg
435 1.1 mrg /*
436 1.1 mrg * If the segment's VA is aligned on a 4MB boundary, align its
437 1.1 mrg * request 4MB aligned physical memory. Otherwise use default
438 1.1 mrg * alignment.
439 1.1 mrg */
440 1.1 mrg align = phdr.p_align;
441 1.1 mrg if ((phdr.p_vaddr & (4*MEG-1)) == 0)
442 1.1 mrg align = 4*MEG;
443 1.1 mrg if (OF_claim((void *)phdr.p_vaddr, phdr.p_memsz, phdr.p_align) ==
444 1.1 mrg (void *)-1)
445 1.1 mrg panic("cannot claim memory");
446 1.1 mrg if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
447 1.1 mrg phdr.p_filesz) {
448 1.1 mrg printf("read segment: %s\n", strerror(errno));
449 1.1 mrg return (1);
450 1.1 mrg }
451 1.1 mrg syncicache((void *)phdr.p_vaddr, phdr.p_filesz);
452 1.1 mrg
453 1.1 mrg /* Zero BSS. */
454 1.1 mrg if (phdr.p_filesz < phdr.p_memsz) {
455 1.1 mrg printf("+%lu@0x%lx", phdr.p_memsz - phdr.p_filesz,
456 1.1 mrg (u_long)(phdr.p_vaddr + phdr.p_filesz));
457 1.1 mrg bzero((void*)phdr.p_vaddr + phdr.p_filesz,
458 1.1 mrg phdr.p_memsz - phdr.p_filesz);
459 1.1 mrg }
460 1.1 mrg first = 0;
461 1.1 mrg }
462 1.1 mrg
463 1.1 mrg printf(" \n");
464 1.1 mrg
465 1.1 mrg #if 1 /* I want to rethink this... --thorpej (at) netbsd.org */
466 1.1 mrg /*
467 1.1 mrg * Compute the size of the symbol table.
468 1.1 mrg */
469 1.1 mrg size = sizeof(Elf32_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
470 1.1 mrg shp = addr = alloc(elf->e_shnum * sizeof(Elf32_Shdr));
471 1.1 mrg (void)lseek(fd, elf->e_shoff, SEEK_SET);
472 1.1 mrg if (read(fd, addr, elf->e_shnum * sizeof(Elf32_Shdr)) !=
473 1.1 mrg elf->e_shnum * sizeof(Elf32_Shdr)) {
474 1.1 mrg printf("read section headers: %s\n", strerror(errno));
475 1.1 mrg return (1);
476 1.1 mrg }
477 1.1 mrg for (i = 0; i < elf->e_shnum; i++, shp++) {
478 1.1 mrg if (shp->sh_type == SHT_NULL)
479 1.1 mrg continue;
480 1.1 mrg if (shp->sh_type != SHT_SYMTAB
481 1.1 mrg && shp->sh_type != SHT_STRTAB) {
482 1.1 mrg shp->sh_offset = 0;
483 1.1 mrg shp->sh_type = SHT_NOBITS;
484 1.1 mrg continue;
485 1.1 mrg }
486 1.1 mrg size += shp->sh_size;
487 1.1 mrg }
488 1.1 mrg shp = addr;
489 1.1 mrg
490 1.1 mrg /*
491 1.1 mrg * Reserve memory for the symbols.
492 1.1 mrg */
493 1.1 mrg if ((addr = OF_claim(0, size, NBPG)) == (void *)-1)
494 1.1 mrg panic("no space for symbol table");
495 1.1 mrg
496 1.1 mrg /*
497 1.1 mrg * Copy the headers.
498 1.1 mrg */
499 1.1 mrg elf->e_phoff = 0;
500 1.1 mrg elf->e_shoff = sizeof(Elf32_Ehdr);
501 1.1 mrg elf->e_phentsize = 0;
502 1.1 mrg elf->e_phnum = 0;
503 1.1 mrg bcopy(elf, addr, sizeof(Elf32_Ehdr));
504 1.1 mrg bcopy(shp, addr + sizeof(Elf32_Ehdr), elf->e_shnum * sizeof(Elf32_Shdr));
505 1.1 mrg free(shp, elf->e_shnum * sizeof(Elf32_Shdr));
506 1.1 mrg *ssymp = addr;
507 1.1 mrg
508 1.1 mrg /*
509 1.1 mrg * Now load the symbol sections themselves.
510 1.1 mrg */
511 1.1 mrg shp = addr + sizeof(Elf32_Ehdr);
512 1.1 mrg addr += sizeof(Elf32_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
513 1.1 mrg off = sizeof(Elf32_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
514 1.1 mrg for (first = 1, i = 0; i < elf->e_shnum; i++, shp++) {
515 1.1 mrg if (shp->sh_type == SHT_SYMTAB
516 1.1 mrg || shp->sh_type == SHT_STRTAB) {
517 1.1 mrg if (first)
518 1.1 mrg printf("symbols @ 0x%lx ", (u_long)addr);
519 1.1 mrg printf("%s%d", first ? "" : "+", shp->sh_size);
520 1.1 mrg (void)lseek(fd, shp->sh_offset, SEEK_SET);
521 1.1 mrg if (read(fd, addr, shp->sh_size) != shp->sh_size) {
522 1.1 mrg printf("read symbols: %s\n", strerror(errno));
523 1.1 mrg return (1);
524 1.1 mrg }
525 1.1 mrg addr += (shp->sh_size+3)&(~3);
526 1.1 mrg shp->sh_offset = off;
527 1.1 mrg off += (shp->sh_size+3)&(~3);
528 1.1 mrg first = 0;
529 1.1 mrg }
530 1.1 mrg }
531 1.1 mrg *esymp = addr;
532 1.1 mrg #endif /* 0 */
533 1.1 mrg
534 1.1 mrg *entryp = elf->e_entry;
535 1.1 mrg return (0);
536 1.1 mrg }
537 1.1 mrg #endif
538 1.1 mrg #endif /* SPARC_BOOT_ELF */
539 1.1 mrg
540 1.1 mrg void
541 1.1 mrg main()
542 1.1 mrg {
543 1.1 mrg extern char bootprog_name[], bootprog_rev[],
544 1.1 mrg bootprog_maker[], bootprog_date[];
545 1.1 mrg int chosen;
546 1.1 mrg char bootline[512]; /* Should check size? */
547 1.1 mrg char *cp;
548 1.1 mrg int i, fd;
549 1.1 mrg
550 1.1 mrg /* Initialize kernelname */
551 1.1 mrg kernelname = kernels[0];
552 1.1 mrg
553 1.1 mrg printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
554 1.1 mrg printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
555 1.1 mrg
556 1.1 mrg /*
557 1.1 mrg * Get the boot arguments from Openfirmware
558 1.1 mrg */
559 1.1 mrg if ((chosen = OF_finddevice("/chosen")) == -1
560 1.1 mrg || OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0
561 1.1 mrg || OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
562 1.1 mrg printf("Invalid Openfirmware environment\n");
563 1.1 mrg exit();
564 1.1 mrg }
565 1.1 mrg /*prom2boot(bootdev);*/
566 1.1 mrg kernelname = kernels[0];
567 1.1 mrg parseargs(bootline, &boothowto);
568 1.1 mrg for (i=0;;) {
569 1.1 mrg kernelname = kernels[i];
570 1.1 mrg if (boothowto & RB_ASKNAME) {
571 1.1 mrg printf("Boot: ");
572 1.1 mrg gets(bootline);
573 1.1 mrg parseargs(bootline, &boothowto);
574 1.1 mrg }
575 1.1 mrg if ((fd = open(bootline, 0)) >= 0)
576 1.1 mrg break;
577 1.1 mrg if (errno)
578 1.1 mrg printf("open %s: %s\n", opened_name, strerror(errno));
579 1.1 mrg /*
580 1.1 mrg * if we have are not in askname mode, and we aren't using the
581 1.1 mrg * prom bootfile, try the next one (if it exits). otherwise,
582 1.1 mrg * go into askname mode.
583 1.1 mrg */
584 1.1 mrg if ((boothowto & RB_ASKNAME) == 0 &&
585 1.1 mrg i != -1 && kernels[++i]) {
586 1.1 mrg printf(": trying %s...\n", kernels[i]);
587 1.1 mrg } else {
588 1.1 mrg printf("\n");
589 1.1 mrg boothowto |= RB_ASKNAME;
590 1.1 mrg }
591 1.1 mrg }
592 1.1 mrg #ifdef __notyet__
593 1.1 mrg OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
594 1.1 mrg cp = bootline;
595 1.1 mrg #else
596 1.1 mrg strcpy(bootline, opened_name);
597 1.1 mrg cp = bootline + strlen(bootline);
598 1.1 mrg *cp++ = ' ';
599 1.1 mrg #endif
600 1.1 mrg *cp = '-';
601 1.1 mrg if (boothowto & RB_ASKNAME)
602 1.1 mrg *++cp = 'a';
603 1.1 mrg if (boothowto & RB_SINGLE)
604 1.1 mrg *++cp = 's';
605 1.1 mrg if (boothowto & RB_KDB)
606 1.1 mrg *++cp = 'd';
607 1.1 mrg if (*cp == '-')
608 1.1 mrg #ifdef __notyet__
609 1.1 mrg *cp = 0;
610 1.1 mrg #else
611 1.1 mrg *--cp = 0;
612 1.1 mrg #endif
613 1.1 mrg else
614 1.1 mrg *++cp = 0;
615 1.1 mrg #ifdef __notyet__
616 1.1 mrg OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
617 1.1 mrg #endif
618 1.1 mrg /* XXX void, for now */
619 1.1 mrg #ifdef DEBUG
620 1.1 mrg if (debug)
621 1.1 mrg printf("main: Calling loadfile(fd, %s)\n", bootline);
622 1.1 mrg #endif
623 1.1 mrg (void)loadfile(fd, bootline);
624 1.1 mrg
625 1.1 mrg _rtt();
626 1.1 mrg }
627