Home | History | Annotate | Line # | Download | only in boot
boot.c revision 1.3
      1  1.3       he /*	$NetBSD: boot.c,v 1.3 2005/06/09 16:02:19 he Exp $	*/
      2  1.1  tsutsui 
      3  1.1  tsutsui /*-
      4  1.1  tsutsui  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  1.1  tsutsui  * All rights reserved.
      6  1.1  tsutsui  *
      7  1.1  tsutsui  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  tsutsui  * by Jonathan Stone, Michael Hitch and Simon Burge.
      9  1.1  tsutsui  *
     10  1.1  tsutsui  * Redistribution and use in source and binary forms, with or without
     11  1.1  tsutsui  * modification, are permitted provided that the following conditions
     12  1.1  tsutsui  * are met:
     13  1.1  tsutsui  * 1. Redistributions of source code must retain the above copyright
     14  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer.
     15  1.1  tsutsui  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  tsutsui  *    documentation and/or other materials provided with the distribution.
     18  1.1  tsutsui  * 3. All advertising materials mentioning features or use of this software
     19  1.1  tsutsui  *    must display the following acknowledgement:
     20  1.1  tsutsui  *        This product includes software developed by the NetBSD
     21  1.1  tsutsui  *        Foundation, Inc. and its contributors.
     22  1.1  tsutsui  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1  tsutsui  *    contributors may be used to endorse or promote products derived
     24  1.1  tsutsui  *    from this software without specific prior written permission.
     25  1.1  tsutsui  *
     26  1.1  tsutsui  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1  tsutsui  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1  tsutsui  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1  tsutsui  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1  tsutsui  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1  tsutsui  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1  tsutsui  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1  tsutsui  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1  tsutsui  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1  tsutsui  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1  tsutsui  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1  tsutsui  */
     38  1.1  tsutsui 
     39  1.1  tsutsui /*
     40  1.1  tsutsui  * Copyright (c) 1992, 1993
     41  1.1  tsutsui  *	The Regents of the University of California.  All rights reserved.
     42  1.1  tsutsui  *
     43  1.1  tsutsui  * This code is derived from software contributed to Berkeley by
     44  1.1  tsutsui  * Ralph Campbell.
     45  1.1  tsutsui  *
     46  1.1  tsutsui  * Redistribution and use in source and binary forms, with or without
     47  1.1  tsutsui  * modification, are permitted provided that the following conditions
     48  1.1  tsutsui  * are met:
     49  1.1  tsutsui  * 1. Redistributions of source code must retain the above copyright
     50  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer.
     51  1.1  tsutsui  * 2. Redistributions in binary form must reproduce the above copyright
     52  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer in the
     53  1.1  tsutsui  *    documentation and/or other materials provided with the distribution.
     54  1.1  tsutsui  * 3. Neither the name of the University nor the names of its contributors
     55  1.1  tsutsui  *    may be used to endorse or promote products derived from this software
     56  1.1  tsutsui  *    without specific prior written permission.
     57  1.1  tsutsui  *
     58  1.1  tsutsui  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59  1.1  tsutsui  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60  1.1  tsutsui  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61  1.1  tsutsui  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62  1.1  tsutsui  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  1.1  tsutsui  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  1.1  tsutsui  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  1.1  tsutsui  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  1.1  tsutsui  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  1.1  tsutsui  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  1.1  tsutsui  * SUCH DAMAGE.
     69  1.1  tsutsui  *
     70  1.1  tsutsui  *	@(#)boot.c	8.1 (Berkeley) 6/10/93
     71  1.1  tsutsui  */
     72  1.1  tsutsui 
     73  1.1  tsutsui #include <lib/libsa/stand.h>
     74  1.1  tsutsui #include <lib/libsa/loadfile.h>
     75  1.1  tsutsui #include <lib/libkern/libkern.h>
     76  1.1  tsutsui 
     77  1.1  tsutsui #include <sys/param.h>
     78  1.1  tsutsui #include <sys/exec.h>
     79  1.1  tsutsui #include <sys/exec_elf.h>
     80  1.1  tsutsui #include <sys/boot_flag.h>
     81  1.1  tsutsui 
     82  1.1  tsutsui #include <dev/arcbios/arcbios.h>
     83  1.1  tsutsui 
     84  1.1  tsutsui #include "common.h"
     85  1.1  tsutsui #include "bootinfo.h"
     86  1.1  tsutsui 
     87  1.1  tsutsui #ifdef BOOT_DEBUG
     88  1.1  tsutsui #define DPRINTF if (debug) printf
     89  1.1  tsutsui #else
     90  1.1  tsutsui #define DPRINTF while (/*CONSTCOND*/0) printf
     91  1.1  tsutsui #endif
     92  1.1  tsutsui 
     93  1.1  tsutsui /*
     94  1.1  tsutsui  * We won't go overboard with gzip'd kernel names.  After all we can
     95  1.1  tsutsui  * still boot a gzip'd kernel called "netbsd.arc" - it doesn't need
     96  1.1  tsutsui  * the .gz suffix.
     97  1.1  tsutsui  *
     98  1.1  tsutsui  * For arcane reasons, the first byte of the first element of this struct will
     99  1.1  tsutsui  * contain a zero.  We therefore start from one.
    100  1.1  tsutsui  */
    101  1.1  tsutsui 
    102  1.1  tsutsui char *kernelnames[] = {
    103  1.1  tsutsui 	"placekeeper",
    104  1.2  thorpej 	"netbsd.arc",
    105  1.1  tsutsui 	"netbsd",
    106  1.1  tsutsui 	"netbsd.gz",
    107  1.1  tsutsui 	"netbsd.bak",
    108  1.1  tsutsui 	"netbsd.old",
    109  1.1  tsutsui 	"onetbsd",
    110  1.1  tsutsui 	"gennetbsd",
    111  1.1  tsutsui 	NULL
    112  1.1  tsutsui };
    113  1.1  tsutsui 
    114  1.1  tsutsui static int debug = 0;
    115  1.1  tsutsui static char **environment;
    116  1.1  tsutsui 
    117  1.1  tsutsui /* Storage must be static. */
    118  1.1  tsutsui struct btinfo_symtab bi_syms;
    119  1.1  tsutsui struct btinfo_bootpath bi_bpath;
    120  1.1  tsutsui 
    121  1.1  tsutsui extern const struct arcbios_fv *ARCBIOS;
    122  1.1  tsutsui 
    123  1.1  tsutsui int main(int, char **);
    124  1.1  tsutsui static char *firmware_getenv(char *);
    125  1.1  tsutsui 
    126  1.1  tsutsui /*
    127  1.1  tsutsui  * This gets arguments from the ARCS monitor, calls ARCS routines to open
    128  1.1  tsutsui  * and load the program to boot, then transfers execution to the new program.
    129  1.1  tsutsui  *
    130  1.1  tsutsui  * argv[0] will be the ARCS path to the bootloader (i.e.,
    131  1.1  tsutsui  * "scsi(0)disk(2)rdisk(0)partition(1)\boot").
    132  1.1  tsutsui  *
    133  1.1  tsutsui  * argv[1] through argv[n] will contain arguments passed from the PROM, if any.
    134  1.1  tsutsui  */
    135  1.1  tsutsui 
    136  1.1  tsutsui int
    137  1.1  tsutsui main(int argc, char **argv)
    138  1.1  tsutsui {
    139  1.3       he 	const char     *kernel = NULL;
    140  1.3       he 	const char     *bootpath = NULL;
    141  1.1  tsutsui 	char            bootfile[PATH_MAX];
    142  1.1  tsutsui 	void            (*entry)(int, char *[], int, void *);
    143  1.1  tsutsui 	u_long          marks[MARK_MAX];
    144  1.1  tsutsui 	int             win = 0;
    145  1.1  tsutsui 	int             i;
    146  1.1  tsutsui 	int             ch;
    147  1.1  tsutsui 
    148  1.1  tsutsui 	/* print a banner */
    149  1.1  tsutsui 	printf("\n");
    150  1.1  tsutsui 	printf("%s Bootstrap, Revision %s\n", bootprog_name, bootprog_rev);
    151  1.1  tsutsui 	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
    152  1.1  tsutsui 
    153  1.1  tsutsui 	memset(marks, 0, sizeof marks);
    154  1.1  tsutsui 
    155  1.1  tsutsui 	/* initialise bootinfo structure early */
    156  1.1  tsutsui 	bi_init();
    157  1.1  tsutsui 
    158  1.1  tsutsui #ifdef BOOT_DEBUG
    159  1.1  tsutsui 	for (i = 0; i < argc; i++)
    160  1.1  tsutsui 		printf("argv[%d] = %s\n", i, argv[i]);
    161  1.1  tsutsui #endif
    162  1.1  tsutsui 
    163  1.1  tsutsui 	/* Parse arguments, if present.  */
    164  1.1  tsutsui 	while ((ch = getopt(argc, argv, "v")) != -1) {
    165  1.1  tsutsui 		switch (ch) {
    166  1.1  tsutsui 		case 'v':
    167  1.1  tsutsui 			debug = 1;
    168  1.1  tsutsui 			break;
    169  1.1  tsutsui 		}
    170  1.1  tsutsui 	}
    171  1.1  tsutsui 
    172  1.1  tsutsui 	environment = &argv[1];
    173  1.1  tsutsui 
    174  1.1  tsutsui 	bootpath = firmware_getenv("OSLoadPartition");
    175  1.1  tsutsui 	if (bootpath == NULL)
    176  1.1  tsutsui 		bootpath =
    177  1.1  tsutsui 		    (*ARCBIOS->GetEnvironmentVariable)("OSLoadPartition");
    178  1.1  tsutsui 
    179  1.1  tsutsui 	if (bootpath == NULL) {
    180  1.1  tsutsui 		/* XXX need to actually do the fixup */
    181  1.1  tsutsui 		printf("OSLoadPartition is not specified.\n");
    182  1.1  tsutsui 		return 0;
    183  1.1  tsutsui 	}
    184  1.1  tsutsui 	DPRINTF("bootpath = %s\n", bootpath);
    185  1.1  tsutsui 
    186  1.1  tsutsui 	/*
    187  1.1  tsutsui 	 * Grab OSLoadFilename from ARCS.
    188  1.1  tsutsui 	 */
    189  1.1  tsutsui 
    190  1.1  tsutsui 	kernel = firmware_getenv("OSLoadFilename");
    191  1.1  tsutsui 	if (kernel == NULL)
    192  1.1  tsutsui 		kernel = (*ARCBIOS->GetEnvironmentVariable)("OSLoadFilename");
    193  1.1  tsutsui 
    194  1.1  tsutsui 	DPRINTF("kernel = %s\n", kernel ? kernel : "<null>");
    195  1.1  tsutsui 
    196  1.1  tsutsui 	/*
    197  1.1  tsutsui 	 * The first arg is assumed to contain the name of the kernel to boot,
    198  1.1  tsutsui 	 * if it a) does not start with a hyphen and b) does not contain
    199  1.1  tsutsui 	 * an equals sign.
    200  1.1  tsutsui 	 */
    201  1.1  tsutsui 
    202  1.1  tsutsui 	for (i = 1; i < argc; i++) {
    203  1.1  tsutsui 		if (((strchr(argv[i], '=')) == NULL) && (argv[i][0] != '-')) {
    204  1.1  tsutsui 			kernel = argv[i];
    205  1.1  tsutsui 			break;
    206  1.1  tsutsui 		}
    207  1.1  tsutsui 	}
    208  1.1  tsutsui 
    209  1.1  tsutsui 	if (kernel != NULL) {
    210  1.1  tsutsui 		/*
    211  1.1  tsutsui 		 * if the name contains parenthesis, we assume that it
    212  1.1  tsutsui 		 * contains the bootpath and ignore anything passed through
    213  1.1  tsutsui 		 * the environment
    214  1.1  tsutsui 		 */
    215  1.1  tsutsui 		if (strchr(kernel, '('))
    216  1.1  tsutsui 			win = loadfile(kernel, marks, LOAD_KERNEL);
    217  1.1  tsutsui 		else {
    218  1.1  tsutsui 			strcpy(bootfile, bootpath);
    219  1.1  tsutsui 			strcat(bootfile, kernel);
    220  1.1  tsutsui 			win = loadfile(bootfile, marks, LOAD_KERNEL);
    221  1.1  tsutsui 		}
    222  1.1  tsutsui 
    223  1.1  tsutsui 	} else {
    224  1.1  tsutsui 		i = 1;
    225  1.1  tsutsui 		while (kernelnames[i] != NULL) {
    226  1.1  tsutsui 			strcpy(bootfile, bootpath);
    227  1.1  tsutsui 			strcat(bootfile, kernelnames[i]);
    228  1.1  tsutsui 			kernel = kernelnames[i];
    229  1.1  tsutsui 			win = loadfile(bootfile, marks, LOAD_KERNEL);
    230  1.1  tsutsui 			if (win != -1)
    231  1.1  tsutsui 				break;
    232  1.1  tsutsui 			i++;
    233  1.1  tsutsui 		}
    234  1.1  tsutsui 
    235  1.1  tsutsui 	}
    236  1.1  tsutsui 
    237  1.1  tsutsui 	if (win < 0) {
    238  1.1  tsutsui 		printf("Boot failed!  Halting...\n");
    239  1.1  tsutsui 		(void)getchar();
    240  1.1  tsutsui 		return 0;
    241  1.1  tsutsui 	}
    242  1.1  tsutsui 
    243  1.1  tsutsui #if 0
    244  1.1  tsutsui 	strncpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN);
    245  1.1  tsutsui 	bi_add(&bi_bpath, BTINFO_BOOTPATH);
    246  1.1  tsutsui 
    247  1.1  tsutsui 	bi_syms.nsym = marks[MARK_NSYM];
    248  1.1  tsutsui 	bi_syms.ssym = marks[MARK_SYM];
    249  1.1  tsutsui 	bi_syms.esym = marks[MARK_END];
    250  1.1  tsutsui 	bi_add(&bi_syms, BTINFO_SYMTAB);
    251  1.1  tsutsui #endif
    252  1.1  tsutsui 	entry = (void *)marks[MARK_ENTRY];
    253  1.1  tsutsui 
    254  1.1  tsutsui 	if (debug) {
    255  1.1  tsutsui 		printf("Starting at %p\n\n", entry);
    256  1.1  tsutsui 		printf("nsym 0x%lx ssym 0x%lx esym 0x%lx\n", marks[MARK_NSYM],
    257  1.1  tsutsui 		       marks[MARK_SYM], marks[MARK_END]);
    258  1.1  tsutsui 	}
    259  1.1  tsutsui 	(*entry)(argc, argv, 0 /* BOOTINFO_MAGIC */, NULL);
    260  1.1  tsutsui 
    261  1.1  tsutsui 	printf("Kernel returned!  Halting...\n");
    262  1.1  tsutsui 	return 0;
    263  1.1  tsutsui }
    264  1.1  tsutsui 
    265  1.1  tsutsui char *
    266  1.1  tsutsui firmware_getenv(char *envname)
    267  1.1  tsutsui {
    268  1.1  tsutsui 	char **env;
    269  1.1  tsutsui 	int len;
    270  1.1  tsutsui 
    271  1.1  tsutsui 	len = strlen(envname);
    272  1.1  tsutsui 
    273  1.1  tsutsui 	for (env = environment; env[0]; env++) {
    274  1.1  tsutsui 		if (strncasecmp(envname, env[0], len) == 0 &&
    275  1.1  tsutsui 		    env[0][len] == '=') {
    276  1.1  tsutsui 			return &env[0][len + 1];
    277  1.1  tsutsui 		}
    278  1.1  tsutsui 	}
    279  1.1  tsutsui 	return NULL;
    280  1.1  tsutsui }
    281  1.1  tsutsui 
    282  1.1  tsutsui void
    283  1.1  tsutsui _rtt(void)
    284  1.1  tsutsui {
    285  1.1  tsutsui 
    286  1.1  tsutsui 	(*ARCBIOS->Halt)();
    287  1.1  tsutsui }
    288