boot.c revision 1.8
1/* $NetBSD: boot.c,v 1.8 2000/07/25 06:26:19 tsubai Exp $ */ 2 3/*- 4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 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) 1995, 1996 Wolfgang Solfrank. 41 * Copyright (C) 1995, 1996 TooLs GmbH. 42 * All rights reserved. 43 * 44 * ELF support derived from NetBSD/alpha's boot loader, written 45 * by Christopher G. Demetriou. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. All advertising materials mentioning features or use of this software 56 * must display the following acknowledgement: 57 * This product includes software developed by TooLs GmbH. 58 * 4. The name of TooLs GmbH may not be used to endorse or promote products 59 * derived from this software without specific prior written permission. 60 * 61 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 63 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 64 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 65 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 66 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 67 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 68 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 69 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 70 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 71 */ 72 73/* 74 * First try for the boot code 75 * 76 * Input syntax is: 77 * [promdev[{:|,}partition]]/[filename] [flags] 78 */ 79 80#define ELFSIZE 32 /* We use 32-bit ELF. */ 81 82#include <sys/param.h> 83#include <sys/exec.h> 84#include <sys/exec_elf.h> 85#include <sys/reboot.h> 86#include <sys/disklabel.h> 87 88#include <lib/libsa/stand.h> 89#include <lib/libsa/loadfile.h> 90#include <lib/libkern/libkern.h> 91 92#include <machine/cpu.h> 93#include <machine/machine_type.h> 94 95#include "ofdev.h" 96#include "openfirm.h" 97 98char bootdev[128]; 99char bootfile[128]; 100int boothowto; 101int debug; 102 103static ofw_version = 0; 104 105static void 106prom2boot(dev) 107 char *dev; 108{ 109 char *cp; 110 111 cp = dev + strlen(dev) - 1; 112 for (; *cp; cp--) { 113 if (*cp == ':') { 114 if (ofw_version < 3) { 115 /* sd@0:0 -> sd@0 */ 116 *cp = 0; 117 break; 118 } else { 119 /* disk@0:5,boot -> disk@0:0 */ 120 strcpy(cp, ":0"); 121 break; 122 } 123 } 124 } 125} 126 127static void 128parseargs(str, howtop) 129 char *str; 130 int *howtop; 131{ 132 char *cp; 133 134 /* Allow user to drop back to the PROM. */ 135 if (strcmp(str, "exit") == 0) 136 OF_exit(); 137 138 *howtop = 0; 139 140 cp = str; 141 if (*cp == '-') 142 goto found; 143 for (cp = str; *cp; cp++) 144 if (*cp == ' ') 145 goto found; 146 return; 147 148found: 149 *cp++ = 0; 150 while (*cp) { 151 switch (*cp++) { 152 case 'a': 153 *howtop |= RB_ASKNAME; 154 break; 155 case 's': 156 *howtop |= RB_SINGLE; 157 break; 158 case 'd': 159 *howtop |= RB_KDB; 160 debug = 1; 161 break; 162 } 163 } 164} 165 166static void 167chain(entry, args, ssym, esym) 168 void (*entry)(); 169 char *args; 170 void *ssym, *esym; 171{ 172 extern char end[]; 173 int l, machine_tag; 174 175 /* 176 * Stash pointer to end of symbol table after the argument 177 * strings. 178 */ 179 l = strlen(args) + 1; 180 bcopy(&ssym, args + l, sizeof(ssym)); 181 l += sizeof(ssym); 182 bcopy(&esym, args + l, sizeof(esym)); 183 l += sizeof(esym); 184 185 /* 186 * Tell the kernel we're an OpenFirmware system. 187 */ 188 machine_tag = POWERPC_MACHINE_OPENFIRMWARE; 189 bcopy(&machine_tag, args + l, sizeof(machine_tag)); 190 l += sizeof(machine_tag); 191 192 OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l); 193 panic("chain"); 194} 195 196__dead void 197_rtt() 198{ 199 200 OF_exit(); 201} 202 203void 204main() 205{ 206 extern char bootprog_name[], bootprog_rev[], 207 bootprog_maker[], bootprog_date[]; 208 int chosen, options, openprom; 209 char bootline[512]; /* Should check size? */ 210 char *cp; 211 u_long marks[MARK_MAX]; 212 u_int32_t entry; 213 void *ssym, *esym; 214 215 printf("\n"); 216 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 217 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 218 219 /* 220 * Figure out what version of Open Firmware... 221 */ 222 if ((openprom = OF_finddevice("/openprom")) != -1) { 223 char model[32]; 224 225 bzero(model, sizeof model); 226 OF_getprop(openprom, "model", model, sizeof model); 227 for (cp = model; *cp; cp++) 228 if (*cp >= '0' && *cp <= '9') { 229 ofw_version = *cp - '0'; 230 break; 231 } 232#if 0 233 printf(">> Open Firmware version %d.x\n", ofw_version); 234#endif 235 } 236 237 /* 238 * Get the boot arguments from Openfirmware 239 */ 240 if ((chosen = OF_finddevice("/chosen")) == -1 || 241 OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 || 242 OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) { 243 printf("Invalid Openfirmware environment\n"); 244 OF_exit(); 245 } 246 247 /* 248 * Some versions of Openfirmware sets bootpath to "". 249 * We use boot-device instead if it occurs. 250 */ 251 if (bootdev[0] == 0) { 252 printf("Cannot use bootpath\n"); 253 if ((options = OF_finddevice("/options")) == -1 || 254 OF_getprop(options, "boot-device", bootdev, 255 sizeof bootdev) < 0) { 256 printf("Invalid Openfirmware environment\n"); 257 OF_exit(); 258 } 259 printf("Using boot-device instead\n"); 260 } 261 262 prom2boot(bootdev); 263 parseargs(bootline, &boothowto); 264 265 for (;;) { 266 if (boothowto & RB_ASKNAME) { 267 printf("Boot: "); 268 gets(bootline); 269 parseargs(bootline, &boothowto); 270 } 271 marks[MARK_START] = 0; 272 if (loadfile(bootline, marks, LOAD_ALL) >= 0) 273 break; 274 if (errno) 275 printf("open %s: %s\n", opened_name, strerror(errno)); 276 boothowto |= RB_ASKNAME; 277 } 278#ifdef __notyet__ 279 OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1); 280 cp = bootline; 281#else 282 strcpy(bootline, opened_name); 283 cp = bootline + strlen(bootline); 284 *cp++ = ' '; 285#endif 286 *cp = '-'; 287 if (boothowto & RB_ASKNAME) 288 *++cp = 'a'; 289 if (boothowto & RB_SINGLE) 290 *++cp = 's'; 291 if (boothowto & RB_KDB) 292 *++cp = 'd'; 293 if (*cp == '-') 294#ifdef __notyet__ 295 *cp = 0; 296#else 297 *--cp = 0; 298#endif 299 else 300 *++cp = 0; 301#ifdef __notyet__ 302 OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1); 303#endif 304 305 entry = marks[MARK_ENTRY]; 306 ssym = (void *)marks[MARK_SYM]; 307 esym = (void *)marks[MARK_END]; 308 309 printf(" start=0x%x\n", entry); 310 __syncicache((void *)entry, (u_int)ssym - (u_int)entry); 311 chain((void *)entry, bootline, ssym, esym); 312 313 OF_exit(); 314} 315