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