Home | History | Annotate | Line # | Download | only in ofwboot
boot.c revision 1.4.10.1
      1  1.4.10.1   thorpej /*	$NetBSD: boot.c,v 1.4.10.1 1999/06/21 00:55:42 thorpej Exp $	*/
      2       1.2   thorpej 
      3       1.2   thorpej /*-
      4       1.2   thorpej  * Copyright (c) 1997 The NetBSD Foundation, Inc.
      5       1.2   thorpej  * All rights reserved.
      6       1.2   thorpej  *
      7       1.2   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8       1.2   thorpej  * by Jason R. Thorpe.
      9       1.2   thorpej  *
     10       1.2   thorpej  * Redistribution and use in source and binary forms, with or without
     11       1.2   thorpej  * modification, are permitted provided that the following conditions
     12       1.2   thorpej  * are met:
     13       1.2   thorpej  * 1. Redistributions of source code must retain the above copyright
     14       1.2   thorpej  *    notice, this list of conditions and the following disclaimer.
     15       1.2   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.2   thorpej  *    notice, this list of conditions and the following disclaimer in the
     17       1.2   thorpej  *    documentation and/or other materials provided with the distribution.
     18       1.2   thorpej  * 3. All advertising materials mentioning features or use of this software
     19       1.2   thorpej  *    must display the following acknowledgement:
     20       1.2   thorpej  *	This product includes software developed by the NetBSD
     21       1.2   thorpej  *	Foundation, Inc. and its contributors.
     22       1.2   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23       1.2   thorpej  *    contributors may be used to endorse or promote products derived
     24       1.2   thorpej  *    from this software without specific prior written permission.
     25       1.2   thorpej  *
     26       1.2   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27       1.2   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28       1.2   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29       1.2   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30       1.2   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31       1.2   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32       1.2   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33       1.2   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34       1.2   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35       1.2   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36       1.2   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     37       1.2   thorpej  */
     38       1.1   thorpej 
     39       1.1   thorpej /*
     40       1.1   thorpej  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
     41       1.1   thorpej  * Copyright (C) 1995, 1996 TooLs GmbH.
     42       1.1   thorpej  * All rights reserved.
     43       1.1   thorpej  *
     44       1.1   thorpej  * ELF support derived from NetBSD/alpha's boot loader, written
     45       1.1   thorpej  * by Christopher G. Demetriou.
     46       1.1   thorpej  *
     47       1.1   thorpej  * Redistribution and use in source and binary forms, with or without
     48       1.1   thorpej  * modification, are permitted provided that the following conditions
     49       1.1   thorpej  * are met:
     50       1.1   thorpej  * 1. Redistributions of source code must retain the above copyright
     51       1.1   thorpej  *    notice, this list of conditions and the following disclaimer.
     52       1.1   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     53       1.1   thorpej  *    notice, this list of conditions and the following disclaimer in the
     54       1.1   thorpej  *    documentation and/or other materials provided with the distribution.
     55       1.1   thorpej  * 3. All advertising materials mentioning features or use of this software
     56       1.1   thorpej  *    must display the following acknowledgement:
     57       1.1   thorpej  *	This product includes software developed by TooLs GmbH.
     58       1.1   thorpej  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     59       1.1   thorpej  *    derived from this software without specific prior written permission.
     60       1.1   thorpej  *
     61       1.1   thorpej  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     62       1.1   thorpej  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     63       1.1   thorpej  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     64       1.1   thorpej  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     65       1.1   thorpej  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     66       1.1   thorpej  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     67       1.1   thorpej  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     68       1.1   thorpej  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     69       1.1   thorpej  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     70       1.1   thorpej  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     71       1.1   thorpej  */
     72       1.1   thorpej 
     73       1.1   thorpej /*
     74       1.1   thorpej  * First try for the boot code
     75       1.1   thorpej  *
     76       1.1   thorpej  * Input syntax is:
     77       1.1   thorpej  *	[promdev[{:|,}partition]]/[filename] [flags]
     78       1.1   thorpej  */
     79       1.1   thorpej 
     80       1.1   thorpej #define	ELFSIZE		32		/* We use 32-bit ELF. */
     81       1.1   thorpej 
     82       1.1   thorpej #include <sys/param.h>
     83       1.1   thorpej #include <sys/exec.h>
     84       1.1   thorpej #include <sys/exec_elf.h>
     85       1.1   thorpej #include <sys/reboot.h>
     86       1.1   thorpej #include <sys/disklabel.h>
     87       1.1   thorpej 
     88       1.4   mycroft #include <lib/libsa/stand.h>
     89       1.4   mycroft #include <lib/libkern/libkern.h>
     90       1.4   mycroft 
     91       1.1   thorpej #include <machine/cpu.h>
     92       1.1   thorpej #include <machine/machine_type.h>
     93       1.1   thorpej 
     94       1.4   mycroft #include "ofdev.h"
     95       1.4   mycroft #include "openfirm.h"
     96       1.1   thorpej 
     97       1.1   thorpej char bootdev[128];
     98       1.1   thorpej char bootfile[128];
     99       1.1   thorpej int boothowto;
    100       1.1   thorpej int debug;
    101       1.1   thorpej 
    102       1.1   thorpej #ifdef POWERPC_BOOT_ELF
    103       1.1   thorpej int	elf_exec __P((int, Elf_Ehdr *, u_int32_t *, void **));
    104       1.1   thorpej #endif
    105       1.1   thorpej 
    106       1.1   thorpej #ifdef POWERPC_BOOT_AOUT
    107       1.1   thorpej int	aout_exec __P((int, struct exec *, u_int32_t *, void **));
    108       1.1   thorpej #endif
    109       1.1   thorpej 
    110       1.1   thorpej static void
    111       1.1   thorpej prom2boot(dev)
    112       1.1   thorpej 	char *dev;
    113       1.1   thorpej {
    114       1.4   mycroft 	char *cp;
    115       1.1   thorpej 
    116       1.4   mycroft 	for (cp = dev; *cp != '\0'; cp++)
    117       1.4   mycroft 		if (*cp == ':') {
    118       1.4   mycroft 			*cp = '\0';
    119       1.4   mycroft 			return;
    120       1.4   mycroft 		}
    121       1.1   thorpej }
    122       1.1   thorpej 
    123       1.1   thorpej static void
    124       1.1   thorpej parseargs(str, howtop)
    125       1.1   thorpej 	char *str;
    126       1.1   thorpej 	int *howtop;
    127       1.1   thorpej {
    128       1.1   thorpej 	char *cp;
    129       1.1   thorpej 
    130       1.1   thorpej 	/* Allow user to drop back to the PROM. */
    131       1.1   thorpej 	if (strcmp(str, "exit") == 0)
    132       1.4   mycroft 		OF_exit();
    133       1.1   thorpej 
    134       1.1   thorpej 	*howtop = 0;
    135       1.1   thorpej 	for (cp = str; *cp; cp++)
    136       1.1   thorpej 		if (*cp == ' ' || *cp == '-')
    137       1.1   thorpej 			break;
    138       1.1   thorpej 	if (!*cp)
    139       1.1   thorpej 		return;
    140       1.1   thorpej 
    141       1.1   thorpej 	*cp++ = 0;
    142       1.1   thorpej 	while (*cp) {
    143       1.1   thorpej 		switch (*cp++) {
    144       1.1   thorpej 		case 'a':
    145       1.1   thorpej 			*howtop |= RB_ASKNAME;
    146       1.1   thorpej 			break;
    147       1.1   thorpej 		case 's':
    148       1.1   thorpej 			*howtop |= RB_SINGLE;
    149       1.1   thorpej 			break;
    150       1.1   thorpej 		case 'd':
    151       1.1   thorpej 			*howtop |= RB_KDB;
    152       1.1   thorpej 			debug = 1;
    153       1.1   thorpej 			break;
    154       1.1   thorpej 		}
    155       1.1   thorpej 	}
    156       1.1   thorpej }
    157       1.1   thorpej 
    158       1.1   thorpej static void
    159       1.1   thorpej chain(entry, args, esym)
    160       1.1   thorpej 	void (*entry)();
    161       1.1   thorpej 	char *args;
    162       1.1   thorpej 	void *esym;
    163       1.1   thorpej {
    164       1.1   thorpej 	extern char end[];
    165       1.1   thorpej 	int l, machine_tag;
    166       1.1   thorpej 
    167       1.1   thorpej 	freeall();
    168       1.1   thorpej 
    169       1.1   thorpej 	/*
    170       1.1   thorpej 	 * Stash pointer to end of symbol table after the argument
    171       1.1   thorpej 	 * strings.
    172       1.1   thorpej 	 */
    173       1.1   thorpej 	l = strlen(args) + 1;
    174       1.1   thorpej 	bcopy(&esym, args + l, sizeof(esym));
    175       1.1   thorpej 	l += sizeof(esym);
    176       1.1   thorpej 
    177       1.1   thorpej 	/*
    178       1.1   thorpej 	 * Tell the kernel we're an OpenFirmware system.
    179       1.1   thorpej 	 */
    180       1.1   thorpej 	machine_tag = POWERPC_MACHINE_OPENFIRMWARE;
    181       1.1   thorpej 	bcopy(&machine_tag, args + l, sizeof(machine_tag));
    182       1.1   thorpej 	l += sizeof(machine_tag);
    183       1.1   thorpej 
    184       1.1   thorpej 	OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l);
    185       1.1   thorpej 	panic("chain");
    186       1.1   thorpej }
    187       1.1   thorpej 
    188       1.1   thorpej int
    189       1.1   thorpej loadfile(fd, args)
    190       1.1   thorpej 	int fd;
    191       1.1   thorpej 	char *args;
    192       1.1   thorpej {
    193       1.1   thorpej 	union {
    194       1.1   thorpej #ifdef POWERPC_BOOT_AOUT
    195       1.1   thorpej 		struct exec aout;
    196       1.1   thorpej #endif
    197       1.1   thorpej #ifdef POWERPC_BOOT_ELF
    198       1.1   thorpej 		Elf_Ehdr elf;
    199       1.1   thorpej #endif
    200       1.1   thorpej 	} hdr;
    201       1.1   thorpej 	int rval;
    202       1.1   thorpej 	u_int32_t entry;
    203       1.1   thorpej 	void *esym;
    204       1.1   thorpej 
    205       1.1   thorpej 	rval = 1;
    206       1.1   thorpej 	esym = NULL;
    207       1.1   thorpej 
    208       1.1   thorpej 	/* Load the header. */
    209       1.1   thorpej 	if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
    210       1.1   thorpej 		printf("read header: %s\n", strerror(errno));
    211       1.1   thorpej 		goto err;
    212       1.1   thorpej 	}
    213       1.1   thorpej 
    214       1.1   thorpej 	/* Determine file type, load kernel. */
    215       1.1   thorpej #ifdef POWERPC_BOOT_AOUT
    216       1.1   thorpej 	if (N_BADMAG(hdr.aout) == 0 && N_GETMID(hdr.aout) == MID_POWERPC) {
    217       1.1   thorpej 		rval = aout_exec(fd, &hdr.aout, &entry, &esym);
    218       1.1   thorpej 	} else
    219       1.1   thorpej #endif
    220       1.1   thorpej #ifdef POWERPC_BOOT_ELF
    221       1.1   thorpej 	if (memcmp(Elf_e_ident, hdr.elf.e_ident, Elf_e_siz) == 0) {
    222       1.1   thorpej 		rval = elf_exec(fd, &hdr.elf, &entry, &esym);
    223       1.1   thorpej 	} else
    224       1.1   thorpej #endif
    225       1.1   thorpej 	{
    226       1.1   thorpej 		printf("unknown executable format\n");
    227       1.1   thorpej 	}
    228       1.1   thorpej 
    229       1.1   thorpej 	if (rval)
    230       1.1   thorpej 		goto err;
    231       1.1   thorpej 
    232       1.1   thorpej 	printf(" start=0x%x\n", entry);
    233       1.1   thorpej 
    234       1.1   thorpej 	close(fd);
    235       1.1   thorpej 
    236       1.1   thorpej 	/* XXX this should be replaced w/ a mountroothook. */
    237       1.1   thorpej 	if (floppyboot) {
    238       1.1   thorpej 		printf("Please insert root disk and press ENTER ");
    239       1.1   thorpej 		getchar();
    240       1.1   thorpej 		printf("\n");
    241       1.1   thorpej 	}
    242       1.1   thorpej 
    243       1.1   thorpej 	chain((void *)entry, args, esym);
    244       1.1   thorpej 	/* NOTREACHED */
    245       1.1   thorpej 
    246       1.1   thorpej  err:
    247       1.1   thorpej 	close(fd);
    248       1.1   thorpej 	return (rval);
    249       1.1   thorpej }
    250       1.1   thorpej 
    251       1.4   mycroft __dead void
    252       1.4   mycroft _rtt()
    253       1.4   mycroft {
    254       1.4   mycroft 
    255       1.4   mycroft 	OF_exit();
    256       1.4   mycroft }
    257       1.4   mycroft 
    258       1.1   thorpej #ifdef POWERPC_BOOT_AOUT
    259       1.1   thorpej int
    260       1.1   thorpej aout_exec(fd, hdr, entryp, esymp)
    261       1.1   thorpej 	int fd;
    262       1.1   thorpej 	struct exec *hdr;
    263       1.1   thorpej 	u_int32_t *entryp;
    264       1.1   thorpej 	void **esymp;
    265       1.1   thorpej {
    266       1.1   thorpej 	void *addr;
    267       1.1   thorpej 	int n, *paddr;
    268       1.1   thorpej 
    269       1.1   thorpej 	/* Display the load address (entry point) for a.out. */
    270       1.1   thorpej 	printf("Booting %s @ 0x%lx\n", opened_name, hdr->a_entry);
    271       1.1   thorpej 	addr = (void *)(hdr->a_entry);
    272       1.1   thorpej 
    273       1.1   thorpej 	/*
    274       1.1   thorpej 	 * Determine memory needed for kernel and allocate it from
    275       1.1   thorpej 	 * the firmware.
    276       1.1   thorpej 	 */
    277       1.1   thorpej 	n = hdr->a_text + hdr->a_data + hdr->a_bss + hdr->a_syms + sizeof(int);
    278       1.1   thorpej 	if ((paddr = OF_claim(addr, n, 0)) == (int *)-1)
    279       1.1   thorpej 		panic("cannot claim memory");
    280       1.1   thorpej 
    281       1.1   thorpej 	/* Load text. */
    282       1.1   thorpej 	lseek(fd, N_TXTOFF(*hdr), SEEK_SET);
    283       1.1   thorpej 	printf("%lu", hdr->a_text);
    284       1.1   thorpej 	if (read(fd, paddr, hdr->a_text) != hdr->a_text) {
    285       1.1   thorpej 		printf("read text: %s\n", strerror(errno));
    286       1.1   thorpej 		return (1);
    287       1.1   thorpej 	}
    288  1.4.10.1   thorpej 	__syncicache((void *)paddr, hdr->a_text);
    289       1.1   thorpej 
    290       1.1   thorpej 	/* Load data. */
    291       1.1   thorpej 	printf("+%lu", hdr->a_data);
    292       1.1   thorpej 	if (read(fd, (void *)paddr + hdr->a_text, hdr->a_data) != hdr->a_data) {
    293       1.1   thorpej 		printf("read data: %s\n", strerror(errno));
    294       1.1   thorpej 		return (1);
    295       1.1   thorpej 	}
    296       1.1   thorpej 
    297       1.1   thorpej 	/* Zero BSS. */
    298       1.1   thorpej 	printf("+%lu", hdr->a_bss);
    299       1.1   thorpej 	bzero((void *)paddr + hdr->a_text + hdr->a_data, hdr->a_bss);
    300       1.1   thorpej 
    301       1.1   thorpej 	/* Symbols. */
    302       1.1   thorpej 	*esymp = paddr;
    303       1.1   thorpej 	paddr = (int *)((void *)paddr + hdr->a_text + hdr->a_data + hdr->a_bss);
    304       1.1   thorpej 	*paddr++ = hdr->a_syms;
    305       1.1   thorpej 	if (hdr->a_syms) {
    306       1.1   thorpej 		printf(" [%lu", hdr->a_syms);
    307       1.1   thorpej 		if (read(fd, paddr, hdr->a_syms) != hdr->a_syms) {
    308       1.1   thorpej 			printf("read symbols: %s\n", strerror(errno));
    309       1.1   thorpej 			return (1);
    310       1.1   thorpej 		}
    311       1.1   thorpej 		paddr = (int *)((void *)paddr + hdr->a_syms);
    312       1.1   thorpej 		if (read(fd, &n, sizeof(int)) != sizeof(int)) {
    313       1.1   thorpej 			printf("read symbols: %s\n", strerror(errno));
    314       1.1   thorpej 			return (1);
    315       1.1   thorpej 		}
    316       1.1   thorpej 		if (OF_claim((void *)paddr, n + sizeof(int), 0) == (void *)-1)
    317       1.1   thorpej 			panic("cannot claim memory");
    318       1.1   thorpej 		*paddr++ = n;
    319       1.1   thorpej 		if (read(fd, paddr, n - sizeof(int)) != n - sizeof(int)) {
    320       1.1   thorpej 			printf("read symbols: %s\n", strerror(errno));
    321       1.1   thorpej 			return (1);
    322       1.1   thorpej 		}
    323       1.1   thorpej 		printf("+%d]", n - sizeof(int));
    324       1.1   thorpej 		*esymp = paddr + (n - sizeof(int));
    325       1.1   thorpej 	}
    326       1.1   thorpej 
    327       1.1   thorpej 	*entryp = hdr->a_entry;
    328       1.1   thorpej 	return (0);
    329       1.1   thorpej }
    330       1.1   thorpej #endif /* POWERPC_BOOT_AOUT */
    331       1.1   thorpej 
    332       1.1   thorpej #ifdef POWERPC_BOOT_ELF
    333       1.1   thorpej int
    334       1.1   thorpej elf_exec(fd, elf, entryp, esymp)
    335       1.1   thorpej 	int fd;
    336       1.1   thorpej 	Elf_Ehdr *elf;
    337       1.1   thorpej 	u_int32_t *entryp;
    338       1.1   thorpej 	void **esymp;
    339       1.1   thorpej {
    340       1.1   thorpej 	Elf32_Shdr *shp;
    341       1.1   thorpej 	Elf32_Off off;
    342       1.1   thorpej 	void *addr;
    343       1.1   thorpej 	size_t size;
    344       1.1   thorpej 	int i, first = 1;
    345       1.1   thorpej 	int n;
    346       1.1   thorpej 
    347       1.1   thorpej 	/*
    348       1.1   thorpej 	 * Don't display load address for ELF; it's encoded in
    349       1.1   thorpej 	 * each section.
    350       1.1   thorpej 	 */
    351       1.1   thorpej 	printf("Booting %s\n", opened_name);
    352       1.1   thorpej 
    353       1.1   thorpej 	for (i = 0; i < elf->e_phnum; i++) {
    354       1.1   thorpej 		Elf_Phdr phdr;
    355       1.1   thorpej 		(void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET);
    356       1.1   thorpej 		if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
    357       1.1   thorpej 			printf("read phdr: %s\n", strerror(errno));
    358       1.1   thorpej 			return (1);
    359       1.1   thorpej 		}
    360       1.1   thorpej 		if (phdr.p_type != Elf_pt_load ||
    361       1.1   thorpej 		    (phdr.p_flags & (Elf_pf_w|Elf_pf_x)) == 0)
    362       1.1   thorpej 			continue;
    363       1.1   thorpej 
    364       1.1   thorpej 		/* Read in segment. */
    365       1.1   thorpej 		printf("%s%lu@0x%lx", first ? "" : "+", phdr.p_filesz,
    366       1.1   thorpej 		    (u_long)phdr.p_vaddr);
    367       1.1   thorpej 		(void)lseek(fd, phdr.p_offset, SEEK_SET);
    368       1.1   thorpej 		if (OF_claim((void *)phdr.p_vaddr, phdr.p_memsz, 0) ==
    369       1.1   thorpej 		    (void *)-1)
    370       1.1   thorpej 			panic("cannot claim memory");
    371       1.1   thorpej 		if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
    372       1.1   thorpej 		    phdr.p_filesz) {
    373       1.1   thorpej 			printf("read segment: %s\n", strerror(errno));
    374       1.1   thorpej 			return (1);
    375       1.1   thorpej 		}
    376  1.4.10.1   thorpej 		__syncicache((void *)phdr.p_vaddr, phdr.p_filesz);
    377       1.1   thorpej 
    378       1.1   thorpej 		/* Zero BSS. */
    379       1.1   thorpej 		if (phdr.p_filesz < phdr.p_memsz) {
    380       1.1   thorpej 			printf("+%lu@0x%lx", phdr.p_memsz - phdr.p_filesz,
    381       1.1   thorpej 			    (u_long)(phdr.p_vaddr + phdr.p_filesz));
    382       1.3  sakamoto 			bzero((void *)phdr.p_vaddr + phdr.p_filesz,
    383       1.1   thorpej 			    phdr.p_memsz - phdr.p_filesz);
    384       1.1   thorpej 		}
    385       1.1   thorpej 		first = 0;
    386       1.1   thorpej 	}
    387       1.1   thorpej 
    388       1.1   thorpej 	printf(" \n");
    389       1.1   thorpej 
    390       1.1   thorpej #if 0 /* I want to rethink this... --thorpej (at) netbsd.org */
    391       1.1   thorpej 	/*
    392       1.1   thorpej 	 * Compute the size of the symbol table.
    393       1.1   thorpej 	 */
    394       1.1   thorpej 	size = sizeof(Elf_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
    395       1.1   thorpej 	shp = addr = alloc(elf->e_shnum * sizeof(Elf32_Shdr));
    396       1.1   thorpej 	(void)lseek(fd, elf->e_shoff, SEEK_SET);
    397       1.1   thorpej 	if (read(fd, addr, elf->e_shnum * sizeof(Elf32_Shdr)) !=
    398       1.1   thorpej 	    elf->e_shnum * sizeof(Elf32_Shdr)) {
    399       1.1   thorpej 		printf("read section headers: %s\n", strerror(errno));
    400       1.1   thorpej 		return (1);
    401       1.1   thorpej 	}
    402       1.1   thorpej 	for (i = 0; i < elf->e_shnum; i++, shp++) {
    403       1.1   thorpej 		if (shp->sh_type == Elf_sht_null)
    404       1.1   thorpej 			continue;
    405       1.1   thorpej 		if (shp->sh_type != Elf_sht_symtab
    406       1.1   thorpej 		    && shp->sh_type != Elf_sht_strtab) {
    407       1.1   thorpej 			shp->sh_offset = 0;
    408       1.1   thorpej 			shp->sh_type = Elf_sht_nobits;
    409       1.1   thorpej 			continue;
    410       1.1   thorpej 		}
    411       1.1   thorpej 		size += shp->sh_size;
    412       1.1   thorpej 	}
    413       1.1   thorpej 	shp = addr;
    414       1.1   thorpej 
    415       1.1   thorpej 	/*
    416       1.1   thorpej 	 * Reserve memory for the symbols.
    417       1.1   thorpej 	 */
    418       1.1   thorpej 	if ((addr = OF_claim(0, size, NBPG)) == (void *)-1)
    419       1.1   thorpej 		panic("no space for symbol table");
    420       1.1   thorpej 
    421       1.1   thorpej 	/*
    422       1.1   thorpej 	 * Copy the headers.
    423       1.1   thorpej 	 */
    424       1.1   thorpej 	elf->e_phoff = 0;
    425       1.1   thorpej 	elf->e_shoff = sizeof(Elf_Ehdr);
    426       1.1   thorpej 	elf->e_phentsize = 0;
    427       1.1   thorpej 	elf->e_phnum = 0;
    428       1.1   thorpej 	bcopy(elf, addr, sizeof(Elf_Ehdr));
    429       1.1   thorpej 	bcopy(shp, addr + sizeof(Elf_Ehdr), elf->e_shnum * sizeof(Elf32_Shdr));
    430       1.1   thorpej 	free(shp, elf->e_shnum * sizeof(Elf32_Shdr));
    431       1.1   thorpej 	*ssymp = addr;
    432       1.1   thorpej 
    433       1.1   thorpej 	/*
    434       1.1   thorpej 	 * Now load the symbol sections themselves.
    435       1.1   thorpej 	 */
    436       1.1   thorpej 	shp = addr + sizeof(Elf_Ehdr);
    437       1.1   thorpej 	addr += sizeof(Elf_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
    438       1.1   thorpej 	off = sizeof(Elf_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
    439       1.1   thorpej 	for (first = 1, i = 0; i < elf->e_shnum; i++, shp++) {
    440       1.1   thorpej 		if (shp->sh_type == Elf_sht_symtab
    441       1.1   thorpej 		    || shp->sh_type == Elf_sht_strtab) {
    442       1.1   thorpej 			if (first)
    443       1.1   thorpej 				printf("symbols @ 0x%lx ", (u_long)addr);
    444       1.1   thorpej 			printf("%s%d", first ? "" : "+", shp->sh_size);
    445       1.1   thorpej 			(void)lseek(fd, shp->sh_offset, SEEK_SET);
    446       1.1   thorpej 			if (read(fd, addr, shp->sh_size) != shp->sh_size) {
    447       1.1   thorpej 				printf("read symbols: %s\n", strerror(errno));
    448       1.1   thorpej 				return (1);
    449       1.1   thorpej 			}
    450       1.1   thorpej 			addr += shp->sh_size;
    451       1.1   thorpej 			shp->sh_offset = off;
    452       1.1   thorpej 			off += shp->sh_size;
    453       1.1   thorpej 			first = 0;
    454       1.1   thorpej 		}
    455       1.1   thorpej 	}
    456       1.1   thorpej 	*esymp = addr;
    457       1.1   thorpej #endif /* 0 */
    458       1.1   thorpej 
    459       1.1   thorpej 	*entryp = elf->e_entry;
    460       1.1   thorpej 	return (0);
    461       1.1   thorpej }
    462       1.1   thorpej #endif /* POWERPC_BOOT_ELF */
    463       1.1   thorpej 
    464       1.1   thorpej void
    465       1.1   thorpej main()
    466       1.1   thorpej {
    467       1.1   thorpej 	extern char bootprog_name[], bootprog_rev[],
    468       1.1   thorpej 	    bootprog_maker[], bootprog_date[];
    469       1.1   thorpej 	int chosen;
    470       1.1   thorpej 	char bootline[512];		/* Should check size? */
    471       1.1   thorpej 	char *cp;
    472       1.1   thorpej 	int fd;
    473       1.1   thorpej 
    474       1.1   thorpej 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
    475       1.1   thorpej 	printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
    476       1.1   thorpej 
    477       1.1   thorpej 	/*
    478       1.1   thorpej 	 * Get the boot arguments from Openfirmware
    479       1.1   thorpej 	 */
    480       1.4   mycroft 	if ((chosen = OF_finddevice("/chosen")) == -1 ||
    481       1.4   mycroft 	    OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 ||
    482       1.4   mycroft 	    OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
    483       1.1   thorpej 		printf("Invalid Openfirmware environment\n");
    484       1.4   mycroft 		OF_exit();
    485       1.1   thorpej 	}
    486       1.4   mycroft 
    487       1.1   thorpej 	prom2boot(bootdev);
    488       1.1   thorpej 	parseargs(bootline, &boothowto);
    489       1.4   mycroft 
    490       1.1   thorpej 	for (;;) {
    491       1.1   thorpej 		if (boothowto & RB_ASKNAME) {
    492       1.1   thorpej 			printf("Boot: ");
    493       1.1   thorpej 			gets(bootline);
    494       1.1   thorpej 			parseargs(bootline, &boothowto);
    495       1.1   thorpej 		}
    496       1.1   thorpej 		if ((fd = open(bootline, 0)) >= 0)
    497       1.1   thorpej 			break;
    498       1.1   thorpej 		if (errno)
    499       1.1   thorpej 			printf("open %s: %s\n", opened_name, strerror(errno));
    500       1.1   thorpej 		boothowto |= RB_ASKNAME;
    501       1.1   thorpej 	}
    502       1.1   thorpej #ifdef	__notyet__
    503       1.1   thorpej 	OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
    504       1.1   thorpej 	cp = bootline;
    505       1.1   thorpej #else
    506       1.1   thorpej 	strcpy(bootline, opened_name);
    507       1.1   thorpej 	cp = bootline + strlen(bootline);
    508       1.1   thorpej 	*cp++ = ' ';
    509       1.1   thorpej #endif
    510       1.1   thorpej 	*cp = '-';
    511       1.1   thorpej 	if (boothowto & RB_ASKNAME)
    512       1.1   thorpej 		*++cp = 'a';
    513       1.1   thorpej 	if (boothowto & RB_SINGLE)
    514       1.1   thorpej 		*++cp = 's';
    515       1.1   thorpej 	if (boothowto & RB_KDB)
    516       1.1   thorpej 		*++cp = 'd';
    517       1.1   thorpej 	if (*cp == '-')
    518       1.1   thorpej #ifdef	__notyet__
    519       1.1   thorpej 		*cp = 0;
    520       1.1   thorpej #else
    521       1.1   thorpej 		*--cp = 0;
    522       1.1   thorpej #endif
    523       1.1   thorpej 	else
    524       1.1   thorpej 		*++cp = 0;
    525       1.1   thorpej #ifdef	__notyet__
    526       1.1   thorpej 	OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
    527       1.1   thorpej #endif
    528       1.1   thorpej 	/* XXX void, for now */
    529       1.1   thorpej 	(void)loadfile(fd, bootline);
    530       1.1   thorpej 
    531       1.4   mycroft 	OF_exit();
    532       1.1   thorpej }
    533