1 /* $NetBSD: boot.c,v 1.9 1999/11/08 23:29:56 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 static int bootoptions __P((char *)); 51 #if 0 52 static void promsyms __P((int, struct exec *)); 53 #endif 54 55 int debug; 56 int netif_debug; 57 58 extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; 59 unsigned long esym; 60 char *strtab; 61 int strtablen; 62 char fbuf[80], dbuf[128]; 63 64 int main __P((void)); 65 typedef void (*entry_t)__P((caddr_t, int, int, int, long, long)); 66 67 68 /* 69 * Boot device is derived from ROM provided information, or if there is none, 70 * this list is used in sequence, to find a kernel. 71 */ 72 char *kernels[] = { 73 "netbsd", 74 "netbsd.gz", 75 "netbsd.old", 76 "netbsd.old.gz", 77 "onetbsd", 78 "onetbsd.gz", 79 "vmunix", 80 #ifdef notyet 81 "netbsd.pl", 82 "netbsd.pl.gz", 83 "netbsd.el", 84 "netbsd.el.gz", 85 #endif 86 NULL 87 }; 88 89 int 90 bootoptions(ap) 91 char *ap; 92 { 93 int v = 0; 94 if (ap == NULL || *ap++ != '-') 95 return (0); 96 97 while (*ap != '\0' && *ap != ' ' && *ap != '\t' && *ap != '\n') { 98 switch (*ap) { 99 case 'a': 100 v |= RB_ASKNAME; 101 break; 102 case 's': 103 v |= RB_SINGLE; 104 break; 105 case 'd': 106 v |= RB_KDB; 107 debug = 1; 108 break; 109 } 110 ap++; 111 } 112 113 return (v); 114 } 115 116 int 117 main() 118 { 119 int io, i; 120 char *kernel; 121 int how; 122 u_long marks[MARK_MAX], bootinfo; 123 struct btinfo_symtab bi_sym; 124 void *arg; 125 126 #ifdef HEAP_VARIABLE 127 { 128 extern char end[]; 129 setheap((void *)ALIGN(end), (void *)0xffffffff); 130 } 131 #endif 132 prom_init(); 133 134 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 135 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 136 137 /* 138 * get default kernel. 139 */ 140 prom_bootdevice = prom_getbootpath(); 141 kernel = prom_getbootfile(); 142 how = bootoptions(prom_getbootargs()); 143 144 if (kernel != NULL && *kernel != '\0') { 145 i = -1; /* not using the kernels */ 146 } else { 147 i = 0; 148 kernel = kernels[i]; 149 } 150 151 for (;;) { 152 /* 153 * ask for a kernel first .. 154 */ 155 if (how & RB_ASKNAME) { 156 printf("device[%s] (\"halt\" to halt): ", 157 prom_bootdevice); 158 gets(dbuf); 159 if (strcmp(dbuf, "halt") == 0) 160 _rtt(); 161 if (dbuf[0]) 162 prom_bootdevice = dbuf; 163 printf("boot (press RETURN to try default list): "); 164 gets(fbuf); 165 if (fbuf[0]) 166 kernel = fbuf; 167 else { 168 how &= ~RB_ASKNAME; 169 i = 0; 170 kernel = kernels[i]; 171 } 172 } 173 174 marks[MARK_START] = 0; 175 printf("Booting %s\n", kernel); 176 if ((io = loadfile(kernel, marks, LOAD_KERNEL)) != -1) 177 break; 178 179 /* 180 * if we have are not in askname mode, and we aren't using the 181 * prom bootfile, try the next one (if it exits). otherwise, 182 * go into askname mode. 183 */ 184 if ((how & RB_ASKNAME) == 0 && 185 i != -1 && kernels[++i]) { 186 kernel = kernels[i]; 187 printf(": trying %s...\n", kernel); 188 } else { 189 printf("\n"); 190 how |= RB_ASKNAME; 191 } 192 } 193 194 marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(int) - 1)) & 195 (-sizeof(int)); 196 arg = (prom_version() == PROM_OLDMON) ? (caddr_t)PROM_LOADADDR : romp; 197 #if 0 198 /* Old style cruft; works only with a.out */ 199 marks[MARK_END] |= 0xf0000000; 200 (*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, marks[MARK_END], 201 DDB_MAGIC1); 202 #else 203 /* Should work with both a.out and ELF, but somehow ELF is busted */ 204 bootinfo = bi_init(marks[MARK_END]); 205 bi_sym.nsym = marks[MARK_NSYM]; 206 bi_sym.ssym = marks[MARK_SYM]; 207 bi_sym.esym = marks[MARK_END]; 208 bi_add(&bi_sym, BTINFO_SYMTAB, sizeof(bi_sym)); 209 (*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, bootinfo, DDB_MAGIC2); 210 #endif 211 212 _rtt(); 213 } 214