1 /* $NetBSD: exec.c,v 1.3 1997/03/22 04:15:51 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * Copyright (c) 1996 7 * Matthias Drochner. All rights reserved. 8 * Copyright (c) 1996 9 * Perry E. Metzger. All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)boot.c 8.1 (Berkeley) 6/10/93 40 */ 41 42 /* 43 * starts NetBSD a.out kernel needs lowlevel startup from startprog.S 44 */ 45 46 #include <sys/param.h> 47 #include <sys/exec_aout.h> 48 #include <sys/reboot.h> 49 #ifdef COMPAT_OLDBOOT 50 #include <sys/disklabel.h> 51 #endif 52 53 #include <lib/libsa/stand.h> 54 #include "libi386.h" 55 56 #ifdef COMPAT_OLDBOOT 57 static int 58 dev2major(devname, major) 59 char *devname; 60 int *major; 61 { 62 static char *devices[] = {"wd", "", "fd", "", "sd"}; 63 #define NUMDEVICES (sizeof(devices)/sizeof(char *)) 64 int i; 65 66 for (i = 0; i < NUMDEVICES; i++) 67 if (!strcmp(devname, devices[i])) { 68 *major = i; 69 return (0); 70 } 71 return (-1); 72 } 73 #endif 74 75 int 76 exec_netbsd(file, loadaddr, boothowto, bootdev, consdev) 77 const char *file; 78 physaddr_t loadaddr; 79 int boothowto; 80 char *bootdev, *consdev; /* passed to kernel */ 81 { 82 register int io; 83 struct exec x; 84 int cc, magic; 85 physaddr_t entry; 86 register physaddr_t cp; 87 u_long boot_argv[6]; 88 89 #ifdef COMPAT_OLDBOOT 90 char *fsname, *devname; 91 int unit, part; 92 const char *filename; 93 int bootdevnr; 94 #else 95 u_long xbootinfo[2]; 96 #endif 97 98 #ifdef DEBUG 99 printf("exec: file=%s loadaddr=0x%lx\n", file, loadaddr); 100 #endif 101 io = open(file, 0); 102 if (io < 0) 103 return (-1); 104 105 /* 106 * Read in the exec header, and validate it. 107 */ 108 if (read(io, (char *) &x, sizeof(x)) != sizeof(x)) 109 goto shread; 110 magic = N_GETMAGIC(x); 111 112 if ((magic != ZMAGIC) || (N_GETMID(x) != MID_MACHINE)) { 113 #ifdef DEBUG 114 printf("invalid NetBSD kernel (%o/%ld)\n", magic, N_GETMID(x)); 115 #endif 116 errno = EFTYPE; 117 goto closeout; 118 } 119 entry = x.a_entry & 0xffffff; 120 121 if (!loadaddr) 122 loadaddr = (entry & 0x100000); 123 124 cp = loadaddr; 125 126 /* 127 * Leave a copy of the exec header before the text. 128 * The kernel may use this to verify that the 129 * symbols were loaded by this boot program. 130 */ 131 vpbcopy(&x, cp, sizeof(x)); 132 cp += sizeof(x); 133 /* 134 * Read in the text segment. 135 */ 136 137 printf("%ld", x.a_text); 138 139 if (pread(io, cp, x.a_text - sizeof(x)) != x.a_text - sizeof(x)) 140 goto shread; 141 cp += x.a_text - sizeof(x); 142 143 /* 144 * Read in the data segment. 145 */ 146 147 printf("+%ld", x.a_data); 148 149 if (pread(io, cp, x.a_data) != x.a_data) 150 goto shread; 151 cp += x.a_data; 152 153 /* 154 * Zero out the BSS section. 155 * (Kernel doesn't care, but do it anyway.) 156 */ 157 158 159 printf("+%ld", x.a_bss); 160 161 pbzero(cp, x.a_bss); 162 cp += x.a_bss; 163 164 /* 165 * Read in the symbol table and strings. 166 * (Always set the symtab size word.) 167 */ 168 vpbcopy(&x.a_syms, cp, sizeof(x.a_syms)); 169 cp += sizeof(x.a_syms); 170 171 if (x.a_syms > 0) { 172 173 /* Symbol table and string table length word. */ 174 175 printf("+[%ld", x.a_syms); 176 177 if (pread(io, cp, x.a_syms) != x.a_syms) 178 goto shread; 179 cp += x.a_syms; 180 181 read(io, &cc, sizeof(cc)); 182 183 vpbcopy(&cc, cp, sizeof(cc)); 184 cp += sizeof(cc); 185 186 /* String table. Length word includes itself. */ 187 188 printf("+%d]", cc); 189 190 cc -= sizeof(int); 191 if (cc <= 0) 192 goto shread; 193 if (pread(io, cp, cc) != cc) 194 goto shread; 195 cp += cc; 196 } 197 boot_argv[3] = (((u_int) cp + sizeof(int) - 1)) & (-sizeof(int)); 198 199 printf("=0x%lx\n", cp - loadaddr); 200 201 boot_argv[0] = boothowto; 202 203 #ifdef COMPAT_OLDBOOT 204 /* prepare boot device information for kernel */ 205 if (parsebootfile(file, &fsname, &devname, &unit, &part, &filename) 206 || strcmp(fsname, "ufs")) 207 bootdevnr = 0; /* XXX error out if parse error??? */ 208 else { 209 int major; 210 211 if (strcmp(devname, "hd") == 0) { 212 /* generic BIOS disk, have to guess type */ 213 struct open_file *f = &files[io]; /* XXX */ 214 215 if (biosdisk_gettype(f) == DTYPE_SCSI) 216 devname = "sd"; 217 else 218 devname = "wd"; 219 220 /* 221 * The old boot block performed the following 222 * conversion: 223 * 224 * hdN -> Xd0 225 * 226 * where X is the type specified by the label. 227 * We mimmick that here, for lack of any better 228 * way of doing things. 229 */ 230 unit = 0; 231 } 232 233 if (dev2major(devname, &major)) 234 bootdevnr = 0; /* XXX error out??? */ 235 else 236 bootdevnr = MAKEBOOTDEV(major, 0, 0, unit, part); 237 } 238 239 boot_argv[1] = bootdevnr; 240 boot_argv[2] = 0; /* cyl offset, unused */ 241 #else /* XXX to be specified */ 242 xbootinfo[0] = vtophys(bootdev); 243 xbootinfo[1] = vtophys(consdev); 244 boot_argv[1] = 0; 245 boot_argv[2] = vtophys(xbootinfo); /* XXX cyl offset */ 246 #endif 247 /* 248 * boot_argv[3] = end (set above) 249 */ 250 boot_argv[4] = getextmem(); 251 boot_argv[5] = getbasemem(); 252 253 close(io); 254 255 #ifdef DEBUG 256 printf("Start @ 0x%lx ...\n", entry); 257 #endif 258 259 startprog(entry, 6, boot_argv, 0x90000); 260 panic("exec returned"); 261 262 shread: 263 printf("exec: short read\n"); 264 errno = EIO; 265 closeout: 266 close(io); 267 return (-1); 268 } 269