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