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