exec.c revision 1.4
1/* $NetBSD: exec.c,v 1.4 1997/09/17 18:02:11 drochner 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 55#include "libi386.h" 56#include "bootinfo.h" 57 58#ifdef COMPAT_OLDBOOT 59static int 60dev2major(devname, major) 61 char *devname; 62 int *major; 63{ 64 static char *devices[] = {"wd", "", "fd", "", "sd"}; 65#define NUMDEVICES (sizeof(devices)/sizeof(char *)) 66 int i; 67 68 for (i = 0; i < NUMDEVICES; i++) 69 if (!strcmp(devname, devices[i])) { 70 *major = i; 71 return (0); 72 } 73 return (-1); 74} 75#endif 76 77extern struct btinfo_console btinfo_console; 78 79int 80exec_netbsd(file, loadaddr, boothowto) 81 const char *file; 82 physaddr_t loadaddr; 83 int boothowto; 84{ 85 register int io; 86 struct exec x; 87 int cc, magic; 88 physaddr_t entry; 89 register physaddr_t cp; 90 u_long boot_argv[6]; 91 92#ifdef COMPAT_OLDBOOT 93 char *fsname, *devname; 94 int unit, part; 95 const char *filename; 96 int bootdevnr; 97#endif 98 99#ifdef DEBUG 100 printf("exec: file=%s loadaddr=0x%lx\n", file, loadaddr); 101#endif 102 103 BI_ALLOC(5); /* ??? */ 104 105 BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console)); 106 107 io = open(file, 0); 108 if (io < 0) 109 goto out; 110 111 /* 112 * Read in the exec header, and validate it. 113 */ 114 if (read(io, (char *) &x, sizeof(x)) != sizeof(x)) 115 goto shread; 116 magic = N_GETMAGIC(x); 117 118 if ((magic != ZMAGIC) || (N_GETMID(x) != MID_MACHINE)) { 119#ifdef DEBUG 120 printf("invalid NetBSD kernel (%o/%d)\n", magic, N_GETMID(x)); 121#endif 122 errno = EFTYPE; 123 goto closeout; 124 } 125 entry = x.a_entry & 0xffffff; 126 127 if (!loadaddr) 128 loadaddr = (entry & 0x100000); 129 130 cp = loadaddr; 131 132 /* 133 * Leave a copy of the exec header before the text. 134 * The kernel may use this to verify that the 135 * symbols were loaded by this boot program. 136 */ 137 vpbcopy(&x, cp, sizeof(x)); 138 cp += sizeof(x); 139 /* 140 * Read in the text segment. 141 */ 142 143 printf("%ld", x.a_text); 144 145 if (pread(io, cp, x.a_text - sizeof(x)) != x.a_text - sizeof(x)) 146 goto shread; 147 cp += x.a_text - sizeof(x); 148 149 /* 150 * Read in the data segment. 151 */ 152 153 printf("+%ld", x.a_data); 154 155 if (pread(io, cp, x.a_data) != x.a_data) 156 goto shread; 157 cp += x.a_data; 158 159 /* 160 * Zero out the BSS section. 161 * (Kernel doesn't care, but do it anyway.) 162 */ 163 164 165 printf("+%ld", x.a_bss); 166 167 pbzero(cp, x.a_bss); 168 cp += x.a_bss; 169 170 /* 171 * Read in the symbol table and strings. 172 * (Always set the symtab size word.) 173 */ 174 vpbcopy(&x.a_syms, cp, sizeof(x.a_syms)); 175 cp += sizeof(x.a_syms); 176 177 if (x.a_syms > 0) { 178 179 /* Symbol table and string table length word. */ 180 181 printf("+[%ld", x.a_syms); 182 183 if (pread(io, cp, x.a_syms) != x.a_syms) 184 goto shread; 185 cp += x.a_syms; 186 187 read(io, &cc, sizeof(cc)); 188 189 vpbcopy(&cc, cp, sizeof(cc)); 190 cp += sizeof(cc); 191 192 /* String table. Length word includes itself. */ 193 194 printf("+%d]", cc); 195 196 cc -= sizeof(int); 197 if (cc <= 0) 198 goto shread; 199 if (pread(io, cp, cc) != cc) 200 goto shread; 201 cp += cc; 202 } 203 boot_argv[3] = (((u_int) cp + sizeof(int) - 1)) & (-sizeof(int)); 204 205 printf("=0x%lx\n", cp - loadaddr); 206 207 boot_argv[0] = boothowto; 208 209#ifdef COMPAT_OLDBOOT 210 /* prepare boot device information for kernel */ 211 if (parsebootfile(file, &fsname, &devname, &unit, &part, &filename) 212 || strcmp(fsname, "ufs")) 213 bootdevnr = 0; /* XXX error out if parse error??? */ 214 else { 215 int major; 216 217 if (strcmp(devname, "hd") == 0) { 218 /* generic BIOS disk, have to guess type */ 219 struct open_file *f = &files[io]; /* XXX */ 220 221 if (biosdisk_gettype(f) == DTYPE_SCSI) 222 devname = "sd"; 223 else 224 devname = "wd"; 225 226 /* 227 * The old boot block performed the following 228 * conversion: 229 * 230 * hdN -> Xd0 231 * 232 * where X is the type specified by the label. 233 * We mimmick that here, for lack of any better 234 * way of doing things. 235 */ 236 unit = 0; 237 } 238 239 if (dev2major(devname, &major)) 240 bootdevnr = 0; /* XXX error out??? */ 241 else 242 bootdevnr = MAKEBOOTDEV(major, 0, 0, unit, part); 243 } 244 245 boot_argv[1] = bootdevnr; 246 boot_argv[2] = 0; /* cyl offset, unused */ 247#else /* XXX to be specified */ 248#ifdef PASS_BIOSGEOM 249 bi_getbiosgeom(); 250#endif 251 boot_argv[1] = 0; 252 boot_argv[2] = vtophys(bootinfo); /* cyl offset */ 253#endif 254 /* 255 * boot_argv[3] = end (set above) 256 */ 257 boot_argv[4] = getextmem(); 258 boot_argv[5] = getbasemem(); 259 260 close(io); 261 262#ifdef DEBUG 263 printf("Start @ 0x%lx ...\n", entry); 264#endif 265 266 startprog(entry, 6, boot_argv, 0x90000); 267 panic("exec returned"); 268 269shread: 270 printf("exec: short read\n"); 271 errno = EIO; 272closeout: 273 close(io); 274out: 275 BI_FREE(); 276 bootinfo = 0; 277 return (-1); 278} 279