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