1 /* $OpenBSD: main.c,v 1.5 2008/05/25 16:55:31 miod Exp $ */ 2 /* $NetBSD: boot.c,v 1.1 1997/04/16 20:29:17 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1997 Jason R. Thorpe. All rights reserved. 6 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 7 * Copyright (C) 1995, 1996 TooLs GmbH. 8 * All rights reserved. 9 * 10 * ELF support derived from NetBSD/alpha's boot loader, written 11 * by Christopher G. Demetriou. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by TooLs GmbH. 24 * 4. The name of TooLs GmbH may not be used to endorse or promote products 25 * derived from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 33 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 35 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * First try for the boot code 41 * 42 * Input syntax is: 43 * [promdev[{:|,}partition]]/[filename] [flags] 44 */ 45 46 #define ELFSIZE 32 /* We use 32-bit ELF. */ 47 48 #include <sys/param.h> 49 #include <sys/exec.h> 50 #include <sys/exec_elf.h> 51 #include <sys/reboot.h> 52 #include <sys/disklabel.h> 53 54 #include <lib/libkern/libkern.h> 55 #include <lib/libsa/stand.h> 56 #include <lib/libsa/loadfile.h> 57 #include <stand/boot/cmd.h> 58 59 60 #include <machine/cpu.h> 61 62 #include <macppc/stand/ofdev.h> 63 #include <macppc/stand/openfirm.h> 64 65 char bootdev[128]; 66 int boothowto; 67 int debug; 68 69 70 void 71 get_alt_bootdev(char *, size_t, char *, size_t); 72 73 static void 74 prom2boot(char *dev) 75 { 76 char *cp, *lp = 0; 77 78 for (cp = dev; *cp; cp++) 79 if (*cp == ':') 80 lp = cp; 81 if (!lp) 82 lp = cp; 83 *lp = 0; 84 } 85 86 static void 87 parseargs(char *str, int *howtop) 88 { 89 char *cp; 90 91 /* Allow user to drop back to the PROM. */ 92 if (strcmp(str, "exit") == 0) 93 _rtt(); 94 95 *howtop = 0; 96 if (str[0] == '\0') 97 return; 98 99 cp = str; 100 while (*cp != 0) { 101 /* check for - */ 102 if (*cp == '-') 103 break; /* start of options found */ 104 105 while (*cp != 0 && *cp != ' ') 106 cp++; /* character in the middle of the name, skip */ 107 108 while (*cp == ' ') 109 *cp++ = 0; 110 } 111 if (!*cp) 112 return; 113 114 *cp++ = 0; 115 while (*cp) { 116 switch (*cp++) { 117 case 'a': 118 *howtop |= RB_ASKNAME; 119 break; 120 case 'c': 121 *howtop |= RB_CONFIG; 122 break; 123 case 's': 124 *howtop |= RB_SINGLE; 125 break; 126 case 'd': 127 *howtop |= RB_KDB; 128 debug = 1; 129 break; 130 } 131 } 132 } 133 134 static void 135 chain(void (*entry)(), char *args, void *ssym, void *esym) 136 { 137 extern char end[]; 138 int l; 139 #ifdef __notyet__ 140 int machine_tag; 141 #endif 142 143 freeall(); 144 145 /* 146 * Stash pointer to end of symbol table after the argument 147 * strings. 148 */ 149 l = strlen(args) + 1; 150 bcopy(&ssym, args + l, sizeof(ssym)); 151 l += sizeof(ssym); 152 bcopy(&esym, args + l, sizeof(esym)); 153 l += sizeof(esym); 154 155 #ifdef __notyet__ 156 /* 157 * Tell the kernel we're an OpenFirmware system. 158 */ 159 machine_tag = POWERPC_MACHINE_OPENFIRMWARE; 160 bcopy(&machine_tag, args + l, sizeof(machine_tag)); 161 l += sizeof(machine_tag); 162 #endif 163 164 OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l); 165 panic("chain"); 166 } 167 168 /* 169 * XXX This limits the maximum size of the (uncompressed) bsd.rd to a 170 * little under 11MB. 171 */ 172 #define CLAIM_LIMIT 0x00c00000 173 174 char bootline[512]; 175 176 extern char *kernelfile; 177 int 178 main() 179 { 180 int chosen; 181 182 /* 183 * Get the boot arguments from Openfirmware 184 */ 185 if ((chosen = OF_finddevice("/chosen")) == -1 || 186 OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 || 187 OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) { 188 printf("Invalid Openfirmware environment\n"); 189 exit(); 190 } 191 prom2boot(bootdev); 192 get_alt_bootdev(bootdev, sizeof(bootdev), bootline, sizeof(bootline)); 193 if (bootline[0] != '\0') 194 kernelfile = bootline; 195 196 OF_claim((void *)0x00100000, CLAIM_LIMIT, 0); /* XXX */ 197 boot(0); 198 return 0; 199 } 200 201 void 202 get_alt_bootdev(char *dev, size_t devsz, char *line, size_t linesz) 203 { 204 char *p; 205 int len; 206 /* 207 * if the kernel image specified contains a ':' it is 208 * [device]:[kernel], so separate the two fields. 209 */ 210 p = strrchr(line, ':'); 211 if (p == NULL) 212 return; 213 /* user specified boot device for kernel */ 214 len = p - line + 1; /* str len plus nil */ 215 strlcpy(dev, line, len > devsz ? devsz : len); 216 217 strlcpy(line, p+1, linesz); /* rest of string ater ':' */ 218 } 219 220 221 void 222 devboot(dev_t dev, char *p) 223 { 224 strlcpy(p, bootdev, BOOTDEVLEN); 225 } 226 227 int 228 run_loadfile(u_long *marks, int howto) 229 { 230 char bootline[512]; /* Should check size? */ 231 u_int32_t entry; 232 char *cp; 233 void *ssym, *esym; 234 235 strlcpy(bootline, opened_name, sizeof bootline); 236 cp = bootline + strlen(bootline); 237 *cp++ = ' '; 238 *cp = '-'; 239 if (howto & RB_ASKNAME) 240 *++cp = 'a'; 241 if (howto & RB_CONFIG) 242 *++cp = 'c'; 243 if (howto & RB_SINGLE) 244 *++cp = 's'; 245 if (howto & RB_KDB) 246 *++cp = 'd'; 247 if (*cp == '-') 248 *--cp = 0; 249 else 250 *++cp = 0; 251 252 entry = marks[MARK_ENTRY]; 253 ssym = (void *)marks[MARK_SYM]; 254 esym = (void *)marks[MARK_END]; 255 { 256 u_int32_t lastpage; 257 lastpage = roundup(marks[MARK_END], NBPG); 258 OF_release((void*)lastpage, CLAIM_LIMIT - lastpage); 259 } 260 261 chain((void *)entry, bootline, ssym, esym); 262 263 _rtt(); 264 return 0; 265 } 266 267 int 268 cnspeed(dev_t dev, int sp) 269 { 270 return CONSPEED; 271 } 272 273 char ttyname_buf[8]; 274 275 char * 276 ttyname(int fd) 277 { 278 snprintf(ttyname_buf, sizeof ttyname_buf, "ofc0"); 279 return ttyname_buf; 280 } 281 282 dev_t 283 ttydev(char *name) 284 { 285 return makedev(0,0); 286 } 287