1 /* $NetBSD: exec.c,v 1.23 2008/05/02 15:26:38 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Copyright (c) 1982, 1986, 1990, 1993 31 * The Regents of the University of California. All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. Neither the name of the University nor the names of its contributors 42 * may be used to endorse or promote products derived from this software 43 * without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 * 57 * @(#)boot.c 8.1 (Berkeley) 6/10/93 58 */ 59 60 /* 61 * Copyright (c) 1996 62 * Matthias Drochner. All rights reserved. 63 * Copyright (c) 1996 64 * Perry E. Metzger. All rights reserved. 65 * Copyright (c) 1997 66 * Martin Husemann. All rights reserved. 67 * 68 * Redistribution and use in source and binary forms, with or without 69 * modification, are permitted provided that the following conditions 70 * are met: 71 * 1. Redistributions of source code must retain the above copyright 72 * notice, this list of conditions and the following disclaimer. 73 * 2. Redistributions in binary form must reproduce the above copyright 74 * notice, this list of conditions and the following disclaimer in the 75 * documentation and/or other materials provided with the distribution. 76 * 3. All advertising materials mentioning features or use of this software 77 * must display the following acknowledgement: 78 * This product includes software developed by the University of 79 * California, Berkeley and its contributors. 80 * 4. Neither the name of the University nor the names of its contributors 81 * may be used to endorse or promote products derived from this software 82 * without specific prior written permission. 83 * 84 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 85 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 86 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 87 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 88 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 89 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 90 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 91 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 92 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 93 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 94 * SUCH DAMAGE. 95 * 96 * @(#)boot.c 8.1 (Berkeley) 6/10/93 97 */ 98 99 /* 100 * starts NetBSD a.out kernel 101 * needs lowlevel startup from startprog.S 102 * This is a special version of exec.c to support use of XMS. 103 */ 104 105 #include <sys/param.h> 106 #include <sys/reboot.h> 107 108 #include <lib/libsa/stand.h> 109 #include <lib/libkern/libkern.h> 110 111 #include "loadfile.h" 112 #include "libi386.h" 113 #include "bootinfo.h" 114 #include "bootmod.h" 115 #ifdef SUPPORT_PS2 116 #include "biosmca.h" 117 #endif 118 119 #define BOOT_NARGS 6 120 121 #ifndef PAGE_SIZE 122 #define PAGE_SIZE 4096 123 #endif 124 125 extern struct btinfo_console btinfo_console; 126 127 boot_module_t *boot_modules; 128 bool boot_modules_enabled = true; 129 bool kernel_loaded; 130 131 static struct btinfo_modulelist *btinfo_modulelist; 132 static size_t btinfo_modulelist_size; 133 static uint32_t image_end; 134 135 static uint8_t *module_alloc(size_t); 136 static void module_init(void); 137 138 int 139 exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto) 140 { 141 u_long boot_argv[BOOT_NARGS]; 142 int fd; 143 u_long marks[MARK_MAX]; 144 struct btinfo_symtab btinfo_symtab; 145 u_long extmem; 146 u_long basemem; 147 #ifdef XMS 148 u_long xmsmem; 149 physaddr_t origaddr = loadaddr; 150 #endif 151 152 #ifdef DEBUG 153 printf("exec: file=%s loadaddr=0x%lx\n", 154 file ? file : "NULL", loadaddr); 155 #endif 156 157 BI_ALLOC(32); /* ??? */ 158 159 BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console)); 160 161 extmem = getextmem(); 162 basemem = getbasemem(); 163 164 #ifdef XMS 165 if ((getextmem1() == 0) && (xmsmem = checkxms())) { 166 u_long kernsize; 167 168 /* 169 * With "CONSERVATIVE_MEMDETECT", extmem is 0 because 170 * getextmem() is getextmem1(). Without, the "smart" 171 * methods could fail to report all memory as well. 172 * xmsmem is a few kB less than the actual size, but 173 * better than nothing. 174 */ 175 if (xmsmem > extmem) 176 extmem = xmsmem; 177 /* 178 * Get the size of the kernel 179 */ 180 marks[MARK_START] = loadaddr; 181 if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1) 182 goto out; 183 close(fd); 184 185 kernsize = marks[MARK_END]; 186 kernsize = (kernsize + 1023) / 1024; 187 188 loadaddr = xmsalloc(kernsize); 189 if (!loadaddr) 190 return ENOMEM; 191 } 192 #endif 193 marks[MARK_START] = loadaddr; 194 if ((fd = loadfile(file, marks, LOAD_KERNEL)) == -1) 195 goto out; 196 197 boot_argv[0] = boothowto; 198 boot_argv[1] = 0; 199 boot_argv[2] = vtophys(bootinfo); /* old cyl offset */ 200 /* argv[3] below */ 201 boot_argv[4] = extmem; 202 boot_argv[5] = basemem; 203 204 close(fd); 205 206 /* 207 * Gather some information for the kernel. Do this after the 208 * "point of no return" to avoid memory leaks. 209 * (but before DOS might be trashed in the XMS case) 210 */ 211 #ifdef PASS_BIOSGEOM 212 bi_getbiosgeom(); 213 #endif 214 #ifdef PASS_MEMMAP 215 bi_getmemmap(); 216 #endif 217 218 #ifdef XMS 219 if (loadaddr != origaddr) { 220 /* 221 * We now have done our last DOS IO, so we may 222 * trash the OS. Copy the data from the temporary 223 * buffer to its real address. 224 */ 225 marks[MARK_START] -= loadaddr; 226 marks[MARK_END] -= loadaddr; 227 marks[MARK_SYM] -= loadaddr; 228 marks[MARK_END] -= loadaddr; 229 ppbcopy(loadaddr, origaddr, marks[MARK_END]); 230 } 231 #endif 232 marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) & 233 (-sizeof(int)); 234 boot_argv[3] = marks[MARK_END]; 235 image_end = marks[MARK_END]; 236 kernel_loaded = true; 237 238 /* pull in any modules if necessary */ 239 if (boot_modules_enabled) { 240 module_init(); 241 if (btinfo_modulelist) { 242 BI_ADD(btinfo_modulelist, BTINFO_MODULELIST, 243 btinfo_modulelist_size); 244 } 245 } 246 247 #ifdef DEBUG 248 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY], 249 marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]); 250 #endif 251 252 btinfo_symtab.nsym = marks[MARK_NSYM]; 253 btinfo_symtab.ssym = marks[MARK_SYM]; 254 btinfo_symtab.esym = marks[MARK_END]; 255 BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab)); 256 257 startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv, 258 x86_trunc_page(basemem*1024)); 259 panic("exec returned"); 260 261 out: 262 BI_FREE(); 263 bootinfo = 0; 264 return -1; 265 } 266 267 static uint8_t * 268 module_alloc(size_t len) 269 { 270 uint32_t addr; 271 272 addr = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); 273 image_end += (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); 274 275 #ifdef DEBUG 276 printf("Allocated %d bytes of module memory at %x\n", len, addr); 277 #endif 278 279 return (uint8_t *)addr; 280 } 281 282 static void 283 module_init(void) 284 { 285 struct bi_modulelist_entry *bi; 286 struct stat st; 287 char *buf; 288 boot_module_t *bm; 289 size_t len; 290 off_t off; 291 int err, fd; 292 293 /* First, see which modules are valid and calculate btinfo size */ 294 len = sizeof(struct btinfo_modulelist); 295 for (bm = boot_modules; bm; bm = bm->bm_next) { 296 fd = open(bm->bm_path, 0); 297 if (fd == -1) { 298 printf("WARNING: couldn't open %s\n", bm->bm_path); 299 bm->bm_len = -1; 300 continue; 301 } 302 err = fstat(fd, &st); 303 if (err == -1) { 304 printf("WARNING: couldn't stat %s\n", bm->bm_path); 305 close(fd); 306 bm->bm_len = -1; 307 continue; 308 } 309 bm->bm_len = st.st_size; 310 close(fd); 311 len += sizeof(struct bi_modulelist_entry); 312 } 313 314 /* Allocate the module list */ 315 btinfo_modulelist = alloc(len); 316 if (btinfo_modulelist == NULL) { 317 printf("WARNING: couldn't allocate module list\n"); 318 return; 319 } 320 memset(btinfo_modulelist, 0, len); 321 btinfo_modulelist_size = len; 322 323 /* Fill in btinfo structure */ 324 buf = (char *)btinfo_modulelist; 325 btinfo_modulelist->num = 0; 326 off = sizeof(struct btinfo_modulelist); 327 328 for (bm = boot_modules; bm; bm = bm->bm_next) { 329 if (bm->bm_len == -1) 330 continue; 331 printf("Loading %s ", bm->bm_path); 332 bm->bm_data = module_alloc(bm->bm_len); 333 if (bm->bm_data == NULL) { 334 printf("NO MEMORY\n"); 335 continue; 336 } 337 fd = open(bm->bm_path, 0); 338 if (fd == -1) { 339 printf("ERROR: couldn't open %s\n", bm->bm_path); 340 continue; 341 } 342 len = pread(fd, bm->bm_data, bm->bm_len); 343 if (len != bm->bm_len) { 344 printf(" FAILED\n"); 345 } else { 346 btinfo_modulelist->num++; 347 bi = (struct bi_modulelist_entry *)(buf + off); 348 off += sizeof(struct bi_modulelist_entry); 349 strncpy(bi->path, bm->bm_path, sizeof(bi->path) - 1); 350 bi->base = (uint32_t)bm->bm_data; 351 bi->len = bm->bm_len; 352 bi->type = BI_MODULE_ELF; 353 printf(" \n"); 354 } 355 close(fd); 356 } 357 btinfo_modulelist->endpa = image_end; 358 } 359