1 /* $NetBSD: boot.c,v 1.14 2003/08/07 16:29:15 agc Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jonathan Stone, Michael Hitch and Simon Burge. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * Ralph Campbell. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)boot.c 8.1 (Berkeley) 6/10/93 71 */ 72 73 #include <lib/libsa/stand.h> 74 #include <lib/libsa/loadfile.h> 75 #include <lib/libkern/libkern.h> 76 77 #include <sys/param.h> 78 #include <sys/exec.h> 79 #include <sys/exec_elf.h> 80 81 #include <machine/dec_prom.h> 82 83 #include "common.h" 84 #include "bootinfo.h" 85 86 /* 87 * We won't go overboard with gzip'd kernel names. After all we can 88 * still boot a gzip'd kernel called "netbsd.pmax" - it doesn't need 89 * the .gz suffix. 90 */ 91 char *kernelnames[] = { 92 "netbsd.pmax", 93 "netbsd", "netbsd.gz", 94 "netbsd.bak", 95 "netbsd.old", 96 "onetbsd", 97 "gennetbsd", 98 #ifdef notyet 99 "netbsd.el", 100 #endif /*notyet*/ 101 NULL 102 }; 103 104 105 static char *devname __P((char *)); 106 int main __P((int, char **)); 107 108 /* 109 * This gets arguments from the first stage boot lader, calls PROM routines 110 * to open and load the program to boot, and then transfers execution to 111 * that new program. 112 * 113 * Argv[0] should be something like "rz(0,0,0)netbsd" on a DECstation 3100. 114 * Argv[0,1] should be something like "boot 5/rz0/netbsd" on a DECstation 5000. 115 * The argument "-a" means netbsd should do an automatic reboot. 116 */ 117 int 118 main(argc, argv) 119 int argc; 120 char **argv; 121 { 122 char *name, **namep, *dev, *kernel; 123 char bootname[PATH_MAX], bootpath[PATH_MAX]; 124 int entry, win; 125 u_long marks[MARK_MAX]; 126 struct btinfo_symtab bi_syms; 127 struct btinfo_bootpath bi_bpath; 128 129 /* print a banner */ 130 printf("\n"); 131 printf("NetBSD/pmax " NETBSD_VERS " " BOOT_TYPE_NAME " Bootstrap, Revision %s\n", 132 bootprog_rev); 133 printf("(%s, %s)\n", bootprog_maker, bootprog_date); 134 printf("\n"); 135 136 /* initialise bootinfo structure early */ 137 bi_init(BOOTINFO_ADDR); 138 139 /* check for DS5000 boot */ 140 if (strcmp(argv[0], "boot") == 0) { 141 argc--; 142 argv++; 143 } 144 name = argv[0]; 145 printf("Boot: %s\n", name); 146 147 /* NOTE: devname() can modify bootname[]. */ 148 strcpy(bootname, argv[0]); 149 if ((kernel = devname(bootname)) == NULL) { 150 dev = bootname; 151 name = NULL; 152 } 153 154 memset(marks, 0, sizeof marks); 155 if (name != NULL) 156 win = (loadfile(name, marks, LOAD_KERNEL) == 0); 157 else { 158 win = 0; 159 for (namep = kernelnames, win = 0; *namep != NULL && !win; 160 namep++) { 161 kernel = *namep; 162 strcpy(bootpath, dev); 163 strcat(bootpath, kernel); 164 printf("Loading: %s\n", bootpath); 165 win = (loadfile(bootpath, marks, LOAD_ALL) != -1); 166 if (win) { 167 name = bootpath; 168 } 169 } 170 } 171 if (!win) 172 goto fail; 173 174 strncpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN); 175 bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath)); 176 177 entry = marks[MARK_ENTRY]; 178 bi_syms.nsym = marks[MARK_NSYM]; 179 bi_syms.ssym = marks[MARK_SYM]; 180 bi_syms.esym = marks[MARK_END]; 181 bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms)); 182 183 printf("Starting at 0x%x\n\n", entry); 184 if (callv == &callvec) 185 startprog(entry, entry, argc, argv, 0, 0, 186 BOOTINFO_MAGIC, BOOTINFO_ADDR); 187 else 188 startprog(entry, entry, argc, argv, DEC_PROM_MAGIC, 189 callv, BOOTINFO_MAGIC, BOOTINFO_ADDR); 190 (void)printf("KERNEL RETURNED!\n"); 191 192 fail: 193 (void)printf("Boot failed! Halting...\n"); 194 return (0); 195 } 196 197 198 /* 199 * Check whether or not fname is a device name only or a full 200 * bootpath including the kernel name. This code to do this 201 * is copied from loadfile() in the first stage bootblocks. 202 * Returns the kernel name, or NULL if no kernel name specified. 203 * 204 * NOTE: fname will be modified if it's of the form N/rzY 205 * without a trailing slash. 206 */ 207 static char * 208 devname(fname) 209 char *fname; 210 { 211 char c; 212 213 while ((c = *fname++) != '\0') { 214 if (c == ')') 215 break; 216 if (c != '/') 217 continue; 218 while ((c = *fname++) != '\0') 219 if (c == '/') 220 break; 221 /* 222 * Make "N/rzY" with no trailing '/' valid by adding 223 * the extra '/' before appending 'boot.pmax' to the path. 224 */ 225 if (c != '/') { 226 fname--; 227 *fname++ = '/'; 228 *fname = '\0'; 229 } 230 break; 231 } 232 return (*fname == '\0' ? NULL : fname); 233 } 234