1 /* $NetBSD: exec.c,v 1.9 1999/03/08 00:09:25 fvdl 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 63 static int 64 dev2major(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 82 extern struct btinfo_console btinfo_console; 83 84 int 85 exec_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 #ifdef PASS_BIOSGEOM 116 bi_getbiosgeom(); 117 #endif 118 119 extmem = getextmem(); 120 121 #ifdef XMS 122 if ((getextmem1() == 0) && (xmsmem = checkxms())) { 123 u_long kernsize; 124 125 /* 126 * With "CONSERVATIVE_MEMDETECT", extmem is 0 because 127 * getextmem() is getextmem1(). Without, the "smart" 128 * methods could fail to report all memory as well. 129 * xmsmem is a few kB less than the actual size, but 130 * better than nothing. 131 */ 132 if (xmsmem > extmem) 133 extmem = xmsmem; 134 /* 135 * Get the size of the kernel 136 */ 137 marks[MARK_START] = loadaddr; 138 if ((fd = loadfile(file, marks, COUNT_ALL)) == -1) 139 goto out; 140 close(fd); 141 142 kernsize = marks[MARK_END]; 143 kernsize = (kernsize + 1023) / 1024; 144 145 loadaddr = xmsalloc(kernsize); 146 if (!loadaddr) 147 return(ENOMEM); 148 } 149 #endif 150 marks[MARK_START] = loadaddr; 151 if ((fd = loadfile(file, marks, LOAD_ALL)) == -1) 152 goto out; 153 154 boot_argv[0] = boothowto; 155 156 #ifdef COMPAT_OLDBOOT 157 /* prepare boot device information for kernel */ 158 if (parsebootfile(file, &fsname, &devname, &unit, &part, &filename) 159 || strcmp(fsname, "ufs")) 160 bootdevnr = 0; /* XXX error out if parse error??? */ 161 else { 162 int major; 163 164 if (strcmp(devname, "hd") == 0) { 165 /* generic BIOS disk, have to guess type */ 166 struct open_file *f = &files[fd]; /* XXX */ 167 168 if (biosdisk_gettype(f) == DTYPE_SCSI) 169 devname = "sd"; 170 else 171 devname = "wd"; 172 173 /* 174 * The old boot block performed the following 175 * conversion: 176 * 177 * hdN -> Xd0 178 * 179 * where X is the type specified by the label. 180 * We mimmick that here, for lack of any better 181 * way of doing things. 182 */ 183 unit = 0; 184 } 185 186 if (dev2major(devname, &major)) 187 bootdevnr = 0; /* XXX error out??? */ 188 else 189 bootdevnr = MAKEBOOTDEV(major, 0, 0, unit, part); 190 } 191 192 boot_argv[1] = bootdevnr; 193 #else 194 boot_argv[1] = 0; 195 #endif 196 boot_argv[2] = vtophys(bootinfo); /* old cyl offset */ 197 /* argv[3] below */ 198 boot_argv[4] = extmem; 199 boot_argv[5] = getbasemem(); 200 201 close(fd); 202 203 #ifdef XMS 204 if (loadaddr != origaddr) { 205 /* 206 * We know have done our last DOS IO, so we may 207 * trash the OS. Copy the data from the temporary 208 * buffer to its real adress. 209 */ 210 marks[MARK_START] -= loadaddr; 211 marks[MARK_END] -= loadaddr; 212 marks[MARK_SYM] -= loadaddr; 213 marks[MARK_END] -= loadaddr; 214 ppbcopy(loadaddr, origaddr, marks[MARK_END]); 215 } 216 #endif 217 marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) & 218 (-sizeof(int)); 219 220 boot_argv[3] = marks[MARK_END]; 221 222 223 #ifdef DEBUG 224 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY], 225 marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]); 226 #endif 227 228 btinfo_symtab.nsym = marks[MARK_NSYM]; 229 btinfo_symtab.ssym = marks[MARK_SYM]; 230 btinfo_symtab.esym = marks[MARK_END]; 231 BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab)); 232 233 startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv, 0x90000); 234 panic("exec returned"); 235 236 out: 237 BI_FREE(); 238 bootinfo = 0; 239 return (-1); 240 } 241