exec.c revision 1.8
1/* $NetBSD: exec.c,v 1.8 1999/01/29 18:49:08 christos 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 * Copyright (c) 1997 11 * Martin Husemann. All rights reserved. 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 the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * @(#)boot.c 8.1 (Berkeley) 6/10/93 42 */ 43 44/* 45 * starts NetBSD a.out kernel 46 * needs lowlevel startup from startprog.S 47 * This is a special version of exec.c to support use of XMS. 48 */ 49 50#include <sys/param.h> 51#include <sys/reboot.h> 52#ifdef COMPAT_OLDBOOT 53#include <sys/disklabel.h> 54#endif 55 56#include <lib/libsa/stand.h> 57 58#include "loadfile.h" 59#include "libi386.h" 60#include "bootinfo.h" 61 62#ifdef COMPAT_OLDBOOT 63static int 64dev2major(devname, major) 65 char *devname; 66 int *major; 67{ 68 static char *devices[] = {"wd", "", "fd", "", "sd"}; 69#define NUMDEVICES (sizeof(devices)/sizeof(char *)) 70 int i; 71 72 for (i = 0; i < NUMDEVICES; i++) 73 if (!strcmp(devname, devices[i])) { 74 *major = i; 75 return (0); 76 } 77 return (-1); 78} 79#endif 80#define BOOT_NARGS 6 81 82extern struct btinfo_console btinfo_console; 83 84int 85exec_netbsd(file, loadaddr, boothowto) 86 const char *file; 87 physaddr_t loadaddr; 88 int boothowto; 89{ 90 u_long boot_argv[BOOT_NARGS]; 91 int fd; 92 u_long marks[MARK_MAX]; 93 struct btinfo_symtab btinfo_symtab; 94 u_long extmem; 95#ifdef XMS 96 u_long xmsmem; 97 physaddr_t origaddr = loadaddr; 98#endif 99 100#ifdef COMPAT_OLDBOOT 101 char *fsname, *devname; 102 int unit, part; 103 const char *filename; 104 int bootdevnr; 105#endif 106 107#ifdef DEBUG 108 printf("exec: file=%s loadaddr=0x%lx\n", file, loadaddr); 109#endif 110 111 BI_ALLOC(6); /* ??? */ 112 113 BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console)); 114 115 extmem = getextmem(); 116 117#ifdef XMS 118 if ((getextmem1() == 0) && (xmsmem = checkxms())) { 119 u_long kernsize; 120 121 /* 122 * With "CONSERVATIVE_MEMDETECT", extmem is 0 because 123 * getextmem() is getextmem1(). Without, the "smart" 124 * methods could fail to report all memory as well. 125 * xmsmem is a few kB less than the actual size, but 126 * better than nothing. 127 */ 128 if (xmsmem > extmem) 129 extmem = xmsmem; 130 /* 131 * Get the size of the kernel 132 */ 133 marks[MARK_START] = loadaddr; 134 if ((fd = loadfile(file, marks, COUNT_ALL)) == -1) 135 goto out; 136 close(fd); 137 138 kernsize = marks[MARK_END]; 139 kernsize = (kernsize + 1023) / 1024; 140 141 loadaddr = xmsalloc(kernsize); 142 if (!loadaddr) 143 return(ENOMEM); 144 } 145#endif 146 marks[MARK_START] = loadaddr; 147 if ((fd = loadfile(file, marks, LOAD_ALL)) == -1) 148 goto out; 149 150 boot_argv[0] = boothowto; 151 152#ifdef COMPAT_OLDBOOT 153 /* prepare boot device information for kernel */ 154 if (parsebootfile(file, &fsname, &devname, &unit, &part, &filename) 155 || strcmp(fsname, "ufs")) 156 bootdevnr = 0; /* XXX error out if parse error??? */ 157 else { 158 int major; 159 160 if (strcmp(devname, "hd") == 0) { 161 /* generic BIOS disk, have to guess type */ 162 struct open_file *f = &files[fd]; /* XXX */ 163 164 if (biosdisk_gettype(f) == DTYPE_SCSI) 165 devname = "sd"; 166 else 167 devname = "wd"; 168 169 /* 170 * The old boot block performed the following 171 * conversion: 172 * 173 * hdN -> Xd0 174 * 175 * where X is the type specified by the label. 176 * We mimmick that here, for lack of any better 177 * way of doing things. 178 */ 179 unit = 0; 180 } 181 182 if (dev2major(devname, &major)) 183 bootdevnr = 0; /* XXX error out??? */ 184 else 185 bootdevnr = MAKEBOOTDEV(major, 0, 0, unit, part); 186 } 187 188 boot_argv[1] = bootdevnr; 189#else 190 boot_argv[1] = 0; 191#endif 192 boot_argv[2] = vtophys(bootinfo); /* old cyl offset */ 193 /* argv[3] below */ 194 boot_argv[4] = extmem; 195 boot_argv[5] = getbasemem(); 196 197#ifdef PASS_BIOSGEOM 198 bi_getbiosgeom(); 199#endif 200 close(fd); 201 202#ifdef XMS 203 if (loadaddr != origaddr) { 204 /* 205 * We know have done our last DOS IO, so we may 206 * trash the OS. Copy the data from the temporary 207 * buffer to its real adress. 208 */ 209 marks[MARK_START] -= loadaddr; 210 marks[MARK_END] -= loadaddr; 211 marks[MARK_SYM] -= loadaddr; 212 marks[MARK_END] -= loadaddr; 213 ppbcopy(loadaddr, origaddr, marks[MARK_END]); 214 } 215#endif 216 marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) & 217 (-sizeof(int)); 218 219 boot_argv[3] = marks[MARK_END]; 220 221 222#ifdef DEBUG 223 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY], 224 marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]); 225#endif 226 227 btinfo_symtab.nsym = marks[MARK_NSYM]; 228 btinfo_symtab.ssym = marks[MARK_SYM]; 229 btinfo_symtab.esym = marks[MARK_END]; 230 BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab)); 231 232 startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv, 0x90000); 233 panic("exec returned"); 234 235out: 236 BI_FREE(); 237 bootinfo = 0; 238 return (-1); 239} 240