1 /* $NetBSD: boot.c,v 1.11 2002/03/28 15:46:20 pk Exp $ */ 2 3 /*- 4 * Copyright (c) 1982, 1986, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)boot.c 8.1 (Berkeley) 6/10/93 36 */ 37 38 #include <sys/param.h> 39 #include <sys/reboot.h> 40 #include <sys/exec.h> 41 42 #include <lib/libsa/stand.h> 43 #include <lib/libsa/loadfile.h> 44 45 #include <machine/promlib.h> 46 #include <sparc/stand/common/promdev.h> 47 48 #include "bootinfo.h" 49 50 extern void prom_patch __P((void)); /* prompatch.c */ 51 52 static int bootoptions __P((char *)); 53 #if 0 54 static void promsyms __P((int, struct exec *)); 55 #endif 56 57 int debug; 58 int netif_debug; 59 60 extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; 61 unsigned long esym; 62 char *strtab; 63 int strtablen; 64 char fbuf[80], dbuf[128]; 65 66 int main __P((void)); 67 typedef void (*entry_t)__P((caddr_t, int, int, int, long, long)); 68 69 /* 70 * Boot device is derived from ROM provided information, or if there is none, 71 * this list is used in sequence, to find a kernel. 72 */ 73 char *kernels[] = { 74 "netbsd", 75 "netbsd.gz", 76 "netbsd.old", 77 "netbsd.old.gz", 78 "onetbsd", 79 "onetbsd.gz", 80 "vmunix", 81 #ifdef notyet 82 "netbsd.pl", 83 "netbsd.pl.gz", 84 "netbsd.el", 85 "netbsd.el.gz", 86 #endif 87 NULL 88 }; 89 90 int 91 bootoptions(ap) 92 char *ap; 93 { 94 int v = 0; 95 if (ap == NULL || *ap++ != '-') 96 return (0); 97 98 while (*ap != '\0' && *ap != ' ' && *ap != '\t' && *ap != '\n') { 99 switch (*ap) { 100 case 'a': 101 v |= RB_ASKNAME; 102 break; 103 case 's': 104 v |= RB_SINGLE; 105 break; 106 case 'd': 107 v |= RB_KDB; 108 debug = 1; 109 break; 110 } 111 ap++; 112 } 113 114 return (v); 115 } 116 117 int 118 main() 119 { 120 int io, i; 121 char *kernel; 122 int how; 123 u_long marks[MARK_MAX], bootinfo; 124 struct btinfo_symtab bi_sym; 125 void *arg; 126 127 #ifdef HEAP_VARIABLE 128 { 129 extern char end[]; 130 setheap((void *)ALIGN(end), (void *)0xffffffff); 131 } 132 #endif 133 prom_init(); 134 135 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 136 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 137 138 /* massage machine prom */ 139 prom_patch(); 140 141 /* 142 * get default kernel. 143 */ 144 prom_bootdevice = prom_getbootpath(); 145 kernel = prom_getbootfile(); 146 how = bootoptions(prom_getbootargs()); 147 148 if (kernel != NULL && *kernel != '\0') { 149 i = -1; /* not using the kernels */ 150 } else { 151 i = 0; 152 kernel = kernels[i]; 153 } 154 155 for (;;) { 156 /* 157 * ask for a kernel first .. 158 */ 159 if (how & RB_ASKNAME) { 160 printf("device[%s] (\"halt\" to halt): ", 161 prom_bootdevice); 162 gets(dbuf); 163 if (strcmp(dbuf, "halt") == 0) 164 _rtt(); 165 if (dbuf[0]) 166 prom_bootdevice = dbuf; 167 printf("boot (press RETURN to try default list): "); 168 gets(fbuf); 169 if (fbuf[0]) 170 kernel = fbuf; 171 else { 172 how &= ~RB_ASKNAME; 173 i = 0; 174 kernel = kernels[i]; 175 } 176 } 177 178 marks[MARK_START] = 0; 179 printf("Booting %s\n", kernel); 180 if ((io = loadfile(kernel, marks, LOAD_KERNEL)) != -1) 181 break; 182 183 /* 184 * if we have are not in askname mode, and we aren't using the 185 * prom bootfile, try the next one (if it exits). otherwise, 186 * go into askname mode. 187 */ 188 if ((how & RB_ASKNAME) == 0 && 189 i != -1 && kernels[++i]) { 190 kernel = kernels[i]; 191 printf(": trying %s...\n", kernel); 192 } else { 193 printf("\n"); 194 how |= RB_ASKNAME; 195 } 196 } 197 198 marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(int) - 1)) & 199 (-sizeof(int)); 200 arg = (prom_version() == PROM_OLDMON) ? (caddr_t)PROM_LOADADDR : romp; 201 #if 0 202 /* Old style cruft; works only with a.out */ 203 marks[MARK_END] |= 0xf0000000; 204 (*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, marks[MARK_END], 205 DDB_MAGIC1); 206 #else 207 /* Should work with both a.out and ELF, but somehow ELF is busted */ 208 bootinfo = bi_init(marks[MARK_END]); 209 210 bi_sym.nsym = marks[MARK_NSYM]; 211 bi_sym.ssym = marks[MARK_SYM]; 212 bi_sym.esym = marks[MARK_END]; 213 bi_add(&bi_sym, BTINFO_SYMTAB, sizeof(bi_sym)); 214 215 /* 216 * Add kernel path to bootinfo 217 */ 218 i = sizeof(struct btinfo_common) + strlen(kernel) + 1; 219 /* Impose limit (somewhat arbitrary) */ 220 if (i < BOOTINFO_SIZE / 2) { 221 union { 222 struct btinfo_kernelfile bi_file; 223 char x[i]; 224 } U; 225 strcpy(U.bi_file.name, kernel); 226 bi_add(&U.bi_file, BTINFO_KERNELFILE, i); 227 } 228 229 (*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, bootinfo, DDB_MAGIC2); 230 #endif 231 232 _rtt(); 233 } 234