Home | History | Annotate | Line # | Download | only in ofwboot
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