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