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