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