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