Annotation of src/sys/arch/i386/stand/lib/exec.c, Revision 1.61
1.60 maxv 1: /* $NetBSD: exec.c,v 1.59 2014/04/06 19:18:00 jakllsch Exp $ */
1.23 ad 2:
3: /*-
1.40 ad 4: * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
1.23 ad 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: */
1.1 perry 28:
29: /*
30: * Copyright (c) 1982, 1986, 1990, 1993
31: * The Regents of the University of California. All rights reserved.
1.19 agc 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: /*
1.1 perry 61: * Copyright (c) 1996
62: * Matthias Drochner. All rights reserved.
63: * Copyright (c) 1996
64: * Perry E. Metzger. All rights reserved.
65: *
66: * Redistribution and use in source and binary forms, with or without
67: * modification, are permitted provided that the following conditions
68: * are met:
69: * 1. Redistributions of source code must retain the above copyright
70: * notice, this list of conditions and the following disclaimer.
71: * 2. Redistributions in binary form must reproduce the above copyright
72: * notice, this list of conditions and the following disclaimer in the
73: * documentation and/or other materials provided with the distribution.
74: *
75: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
76: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
77: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
78: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
79: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
81: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
83: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
84: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85: * SUCH DAMAGE.
86: *
87: * @(#)boot.c 8.1 (Berkeley) 6/10/93
88: */
89:
1.2 thorpej 90: /*
1.8 christos 91: * starts NetBSD a.out kernel
92: * needs lowlevel startup from startprog.S
93: * This is a special version of exec.c to support use of XMS.
1.1 perry 94: */
1.8 christos 95:
1.1 perry 96: #include <sys/param.h>
97: #include <sys/reboot.h>
1.40 ad 98: #include <sys/reboot.h>
1.1 perry 99:
1.53 jakllsch 100: #include <i386/multiboot.h>
1.33 joerg 101:
1.1 perry 102: #include <lib/libsa/stand.h>
1.23 ad 103: #include <lib/libkern/libkern.h>
1.4 drochner 104:
1.6 christos 105: #include "loadfile.h"
1.1 perry 106: #include "libi386.h"
1.4 drochner 107: #include "bootinfo.h"
1.23 ad 108: #include "bootmod.h"
1.42 jmcneill 109: #include "vbe.h"
1.16 jdolecek 110: #ifdef SUPPORT_PS2
111: #include "biosmca.h"
112: #endif
1.1 perry 113:
1.6 christos 114: #define BOOT_NARGS 6
1.1 perry 115:
1.23 ad 116: #ifndef PAGE_SIZE
117: #define PAGE_SIZE 4096
118: #endif
119:
1.43 tsutsui 120: #define MODULE_WARNING_SEC 5
1.41 jmcneill 121:
1.4 drochner 122: extern struct btinfo_console btinfo_console;
123:
1.23 ad 124: boot_module_t *boot_modules;
125: bool boot_modules_enabled = true;
126: bool kernel_loaded;
127:
1.47 uebayasi 128: typedef struct userconf_command {
129: char *uc_text;
130: size_t uc_len;
131: struct userconf_command *uc_next;
132: } userconf_command_t;
133: userconf_command_t *userconf_commands = NULL;
134:
1.39 jmcneill 135: static struct btinfo_framebuffer btinfo_framebuffer;
136:
1.23 ad 137: static struct btinfo_modulelist *btinfo_modulelist;
138: static size_t btinfo_modulelist_size;
139: static uint32_t image_end;
1.26 ad 140: static char module_base[64] = "/";
1.40 ad 141: static int howto;
1.23 ad 142:
1.47 uebayasi 143: static struct btinfo_userconfcommands *btinfo_userconfcommands = NULL;
144: static size_t btinfo_userconfcommands_size = 0;
145:
1.41 jmcneill 146: static void module_init(const char *);
1.57 jakllsch 147: static void module_add_common(const char *, uint8_t);
1.23 ad 148:
1.47 uebayasi 149: static void userconf_init(void);
150:
1.34 ad 151: void
1.39 jmcneill 152: framebuffer_configure(struct btinfo_framebuffer *fb)
153: {
154: if (fb)
155: btinfo_framebuffer = *fb;
156: else {
157: btinfo_framebuffer.physaddr = 0;
158: btinfo_framebuffer.flags = 0;
159: }
160: }
161:
162: void
1.34 ad 163: module_add(char *name)
164: {
1.46 jmcneill 165: return module_add_common(name, BM_TYPE_KMOD);
166: }
167:
168: void
169: splash_add(char *name)
170: {
171: return module_add_common(name, BM_TYPE_IMAGE);
172: }
173:
1.49 tls 174: void
175: rnd_add(char *name)
176: {
177: return module_add_common(name, BM_TYPE_RND);
178: }
179:
1.51 jmcneill 180: void
181: fs_add(char *name)
182: {
183: return module_add_common(name, BM_TYPE_FS);
184: }
185:
1.46 jmcneill 186: static void
1.57 jakllsch 187: module_add_common(const char *name, uint8_t type)
1.46 jmcneill 188: {
1.34 ad 189: boot_module_t *bm, *bmp;
190: size_t len;
191: char *str;
192:
1.35 ad 193: while (*name == ' ' || *name == '\t')
194: ++name;
195:
1.34 ad 196: bm = alloc(sizeof(boot_module_t));
197: len = strlen(name) + 1;
198: str = alloc(len);
199: if (bm == NULL || str == NULL) {
200: printf("couldn't allocate module\n");
201: return;
202: }
203: memcpy(str, name, len);
204: bm->bm_path = str;
205: bm->bm_next = NULL;
1.46 jmcneill 206: bm->bm_type = type;
1.34 ad 207: if (boot_modules == NULL)
208: boot_modules = bm;
209: else {
210: for (bmp = boot_modules; bmp->bm_next;
211: bmp = bmp->bm_next)
212: ;
213: bmp->bm_next = bm;
214: }
215: }
216:
1.47 uebayasi 217: void
218: userconf_add(char *cmd)
219: {
220: userconf_command_t *uc;
221: size_t len;
222: char *text;
223:
224: while (*cmd == ' ' || *cmd == '\t')
225: ++cmd;
226:
227: uc = alloc(sizeof(*uc));
228: if (uc == NULL) {
229: printf("couldn't allocate command\n");
230: return;
231: }
232:
233: len = strlen(cmd) + 1;
234: text = alloc(len);
235: if (text == NULL) {
236: dealloc(uc, sizeof(*uc));
237: printf("couldn't allocate command\n");
238: return;
239: }
240: memcpy(text, cmd, len);
241:
242: uc->uc_text = text;
243: uc->uc_len = len;
244: uc->uc_next = NULL;
245:
246: if (userconf_commands == NULL)
247: userconf_commands = uc;
248: else {
249: userconf_command_t *ucp;
250: for (ucp = userconf_commands; ucp->uc_next != NULL;
251: ucp = ucp->uc_next)
252: ;
253: ucp->uc_next = uc;
254: }
255: }
256:
1.32 joerg 257: static int
258: common_load_kernel(const char *file, u_long *basemem, u_long *extmem,
259: physaddr_t loadaddr, int floppy, u_long marks[MARK_MAX])
1.1 perry 260: {
1.32 joerg 261: int fd;
1.8 christos 262: #ifdef XMS
263: u_long xmsmem;
264: physaddr_t origaddr = loadaddr;
265: #endif
266:
1.32 joerg 267: *extmem = getextmem();
268: *basemem = getbasemem();
1.8 christos 269:
270: #ifdef XMS
271: if ((getextmem1() == 0) && (xmsmem = checkxms())) {
272: u_long kernsize;
273:
274: /*
275: * With "CONSERVATIVE_MEMDETECT", extmem is 0 because
276: * getextmem() is getextmem1(). Without, the "smart"
277: * methods could fail to report all memory as well.
278: * xmsmem is a few kB less than the actual size, but
279: * better than nothing.
280: */
1.32 joerg 281: if (xmsmem > *extmem)
282: *extmem = xmsmem;
1.21 junyoung 283: /*
1.8 christos 284: * Get the size of the kernel
285: */
286: marks[MARK_START] = loadaddr;
1.12 christos 287: if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1)
1.32 joerg 288: return EIO;
1.8 christos 289: close(fd);
290:
291: kernsize = marks[MARK_END];
292: kernsize = (kernsize + 1023) / 1024;
293:
294: loadaddr = xmsalloc(kernsize);
295: if (!loadaddr)
1.21 junyoung 296: return ENOMEM;
1.8 christos 297: }
298: #endif
1.7 christos 299: marks[MARK_START] = loadaddr;
1.29 christos 300: if ((fd = loadfile(file, marks,
1.44 christos 301: LOAD_KERNEL & ~(floppy ? LOAD_BACKWARDS : 0))) == -1)
1.32 joerg 302: return EIO;
1.1 perry 303:
1.8 christos 304: close(fd);
1.10 drochner 305:
1.50 dsl 306: /* If the root fs type is unusual, load its module. */
307: if (fsmod != NULL)
1.57 jakllsch 308: module_add_common(fsmod, BM_TYPE_KMOD);
1.34 ad 309:
1.10 drochner 310: /*
311: * Gather some information for the kernel. Do this after the
312: * "point of no return" to avoid memory leaks.
313: * (but before DOS might be trashed in the XMS case)
314: */
315: #ifdef PASS_BIOSGEOM
316: bi_getbiosgeom();
317: #endif
318: #ifdef PASS_MEMMAP
319: bi_getmemmap();
320: #endif
1.8 christos 321:
322: #ifdef XMS
323: if (loadaddr != origaddr) {
324: /*
1.14 ross 325: * We now have done our last DOS IO, so we may
1.8 christos 326: * trash the OS. Copy the data from the temporary
1.20 wiz 327: * buffer to its real address.
1.8 christos 328: */
329: marks[MARK_START] -= loadaddr;
330: marks[MARK_END] -= loadaddr;
331: marks[MARK_SYM] -= loadaddr;
332: marks[MARK_END] -= loadaddr;
333: ppbcopy(loadaddr, origaddr, marks[MARK_END]);
334: }
335: #endif
336: marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) &
337: (-sizeof(int));
1.23 ad 338: image_end = marks[MARK_END];
339: kernel_loaded = true;
1.1 perry 340:
1.32 joerg 341: return 0;
342: }
343:
344: int
1.40 ad 345: exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto, int floppy,
346: void (*callback)(void))
1.32 joerg 347: {
1.54 jakllsch 348: uint32_t boot_argv[BOOT_NARGS];
1.32 joerg 349: u_long marks[MARK_MAX];
350: struct btinfo_symtab btinfo_symtab;
351: u_long extmem;
352: u_long basemem;
353:
354: #ifdef DEBUG
355: printf("exec: file=%s loadaddr=0x%lx\n",
356: file ? file : "NULL", loadaddr);
357: #endif
358:
1.61 ! maxv 359: BI_ALLOC(BTINFO_MAX);
1.32 joerg 360:
361: BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));
362:
1.40 ad 363: howto = boothowto;
364:
1.56 jakllsch 365: memset(marks, 0, sizeof(marks));
366:
1.32 joerg 367: if (common_load_kernel(file, &basemem, &extmem, loadaddr, floppy, marks))
368: goto out;
369:
1.31 joerg 370: boot_argv[0] = boothowto;
371: boot_argv[1] = 0;
372: boot_argv[2] = vtophys(bootinfo); /* old cyl offset */
373: boot_argv[3] = marks[MARK_END];
374: boot_argv[4] = extmem;
375: boot_argv[5] = basemem;
376:
1.23 ad 377: /* pull in any modules if necessary */
378: if (boot_modules_enabled) {
1.41 jmcneill 379: module_init(file);
1.23 ad 380: if (btinfo_modulelist) {
381: BI_ADD(btinfo_modulelist, BTINFO_MODULELIST,
382: btinfo_modulelist_size);
383: }
384: }
1.1 perry 385:
1.47 uebayasi 386: userconf_init();
387: if (btinfo_userconfcommands != NULL)
388: BI_ADD(btinfo_userconfcommands, BTINFO_USERCONFCOMMANDS,
1.58 jakllsch 389: btinfo_userconfcommands_size);
1.47 uebayasi 390:
1.1 perry 391: #ifdef DEBUG
1.8 christos 392: printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
1.7 christos 393: marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
1.1 perry 394: #endif
395:
1.8 christos 396: btinfo_symtab.nsym = marks[MARK_NSYM];
397: btinfo_symtab.ssym = marks[MARK_SYM];
398: btinfo_symtab.esym = marks[MARK_END];
399: BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab));
400:
1.42 jmcneill 401: /* set new video mode if necessary */
402: vbe_commit();
403: BI_ADD(&btinfo_framebuffer, BTINFO_FRAMEBUFFER,
404: sizeof(struct btinfo_framebuffer));
405:
1.40 ad 406: if (callback != NULL)
407: (*callback)();
1.15 dbj 408: startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
1.21 junyoung 409: x86_trunc_page(basemem*1024));
1.1 perry 410: panic("exec returned");
411:
1.4 drochner 412: out:
413: BI_FREE();
1.60 maxv 414: bootinfo = NULL;
1.21 junyoung 415: return -1;
1.1 perry 416: }
1.23 ad 417:
1.41 jmcneill 418: static void
419: extract_device(const char *path, char *buf, size_t buflen)
420: {
1.59 jakllsch 421: size_t i;
1.41 jmcneill 422:
423: if (strchr(path, ':') != NULL) {
424: for (i = 0; i < buflen - 2 && path[i] != ':'; i++)
425: buf[i] = path[i];
426: buf[i++] = ':';
427: buf[i] = '\0';
428: } else
429: buf[0] = '\0';
430: }
431:
1.26 ad 432: static const char *
1.41 jmcneill 433: module_path(boot_module_t *bm, const char *kdev)
1.26 ad 434: {
435: static char buf[256];
1.41 jmcneill 436: char name_buf[256], dev_buf[64];
437: const char *name, *name2, *p;
1.26 ad 438:
439: name = bm->bm_path;
1.33 joerg 440: for (name2 = name; *name2; ++name2) {
441: if (*name2 == ' ' || *name2 == '\t') {
442: strlcpy(name_buf, name, sizeof(name_buf));
1.59 jakllsch 443: if ((uintptr_t)name2 - (uintptr_t)name < sizeof(name_buf))
1.33 joerg 444: name_buf[name2 - name] = '\0';
445: name = name_buf;
446: break;
447: }
448: }
1.41 jmcneill 449: if ((p = strchr(name, ':')) != NULL) {
450: /* device specified, use it */
451: if (p[1] == '/')
452: snprintf(buf, sizeof(buf), "%s", name);
453: else {
454: p++;
455: extract_device(name, dev_buf, sizeof(dev_buf));
456: snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
457: dev_buf, module_base, p, p);
458: }
459: } else {
460: /* device not specified; load from kernel device if known */
1.58 jakllsch 461: if (name[0] == '/')
1.41 jmcneill 462: snprintf(buf, sizeof(buf), "%s%s", kdev, name);
463: else
464: snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
465: kdev, module_base, name, name);
466: }
1.33 joerg 467:
1.26 ad 468: return buf;
469: }
470:
1.36 christos 471: static int
1.41 jmcneill 472: module_open(boot_module_t *bm, int mode, const char *kdev, bool doload)
1.28 chris 473: {
474: int fd;
475: const char *path;
1.36 christos 476:
1.28 chris 477: /* check the expanded path first */
1.41 jmcneill 478: path = module_path(bm, kdev);
1.28 chris 479: fd = open(path, mode);
1.41 jmcneill 480: if (fd != -1) {
481: if ((howto & AB_SILENT) == 0 && doload)
482: printf("Loading %s ", path);
483: } else {
1.28 chris 484: /* now attempt the raw path provided */
485: fd = open(bm->bm_path, mode);
1.41 jmcneill 486: if (fd != -1 && (howto & AB_SILENT) == 0 && doload)
487: printf("Loading %s ", bm->bm_path);
488: }
489: if (!doload && fd == -1) {
490: printf("WARNING: couldn't open %s", bm->bm_path);
491: if (strcmp(bm->bm_path, path) != 0)
492: printf(" (%s)", path);
493: printf("\n");
1.28 chris 494: }
495: return fd;
496: }
497:
1.23 ad 498: static void
1.41 jmcneill 499: module_init(const char *kernel_path)
1.23 ad 500: {
501: struct bi_modulelist_entry *bi;
502: struct stat st;
1.30 joerg 503: const char *machine;
1.41 jmcneill 504: char kdev[64];
1.23 ad 505: char *buf;
506: boot_module_t *bm;
1.59 jakllsch 507: ssize_t len;
1.23 ad 508: off_t off;
1.41 jmcneill 509: int err, fd, nfail = 0;
510:
511: extract_device(kernel_path, kdev, sizeof(kdev));
1.23 ad 512:
1.30 joerg 513: switch (netbsd_elf_class) {
514: case ELFCLASS32:
515: machine = "i386";
516: break;
517: case ELFCLASS64:
518: machine = "amd64";
519: break;
520: default:
521: machine = "generic";
522: break;
523: }
524: if (netbsd_version / 1000000 % 100 == 99) {
525: /* -current */
526: snprintf(module_base, sizeof(module_base),
1.38 rmind 527: "/stand/%s/%d.%d.%d/modules", machine,
1.30 joerg 528: netbsd_version / 100000000,
529: netbsd_version / 1000000 % 100,
530: netbsd_version / 100 % 100);
531: } else if (netbsd_version != 0) {
532: /* release */
533: snprintf(module_base, sizeof(module_base),
1.38 rmind 534: "/stand/%s/%d.%d/modules", machine,
1.30 joerg 535: netbsd_version / 100000000,
536: netbsd_version / 1000000 % 100);
537: }
538:
1.23 ad 539: /* First, see which modules are valid and calculate btinfo size */
540: len = sizeof(struct btinfo_modulelist);
541: for (bm = boot_modules; bm; bm = bm->bm_next) {
1.41 jmcneill 542: fd = module_open(bm, 0, kdev, false);
1.23 ad 543: if (fd == -1) {
544: bm->bm_len = -1;
1.41 jmcneill 545: ++nfail;
1.23 ad 546: continue;
547: }
548: err = fstat(fd, &st);
1.24 ad 549: if (err == -1 || st.st_size == -1) {
1.28 chris 550: printf("WARNING: couldn't stat %s\n", bm->bm_path);
1.23 ad 551: close(fd);
552: bm->bm_len = -1;
1.41 jmcneill 553: ++nfail;
1.23 ad 554: continue;
555: }
556: bm->bm_len = st.st_size;
557: close(fd);
558: len += sizeof(struct bi_modulelist_entry);
559: }
560:
561: /* Allocate the module list */
562: btinfo_modulelist = alloc(len);
563: if (btinfo_modulelist == NULL) {
564: printf("WARNING: couldn't allocate module list\n");
1.43 tsutsui 565: wait_sec(MODULE_WARNING_SEC);
1.23 ad 566: return;
567: }
568: memset(btinfo_modulelist, 0, len);
569: btinfo_modulelist_size = len;
570:
571: /* Fill in btinfo structure */
572: buf = (char *)btinfo_modulelist;
573: btinfo_modulelist->num = 0;
574: off = sizeof(struct btinfo_modulelist);
575:
576: for (bm = boot_modules; bm; bm = bm->bm_next) {
577: if (bm->bm_len == -1)
578: continue;
1.41 jmcneill 579: fd = module_open(bm, 0, kdev, true);
580: if (fd == -1)
1.23 ad 581: continue;
1.24 ad 582: image_end = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
1.52 jakllsch 583: len = pread(fd, (void *)(uintptr_t)image_end, SSIZE_MAX);
1.24 ad 584: if (len < bm->bm_len) {
1.40 ad 585: if ((howto & AB_SILENT) != 0)
586: printf("Loading %s ", bm->bm_path);
1.23 ad 587: printf(" FAILED\n");
588: } else {
589: btinfo_modulelist->num++;
590: bi = (struct bi_modulelist_entry *)(buf + off);
591: off += sizeof(struct bi_modulelist_entry);
592: strncpy(bi->path, bm->bm_path, sizeof(bi->path) - 1);
1.24 ad 593: bi->base = image_end;
594: bi->len = len;
1.49 tls 595: switch (bm->bm_type) {
596: case BM_TYPE_KMOD:
597: bi->type = BI_MODULE_ELF;
598: break;
599: case BM_TYPE_IMAGE:
600: bi->type = BI_MODULE_IMAGE;
601: break;
1.51 jmcneill 602: case BM_TYPE_FS:
603: bi->type = BI_MODULE_FS;
604: break;
1.49 tls 605: case BM_TYPE_RND:
606: default:
607: /* safest -- rnd checks the sha1 */
608: bi->type = BI_MODULE_RND;
609: break;
610: }
1.40 ad 611: if ((howto & AB_SILENT) == 0)
612: printf(" \n");
1.23 ad 613: }
1.24 ad 614: if (len > 0)
615: image_end += len;
1.23 ad 616: close(fd);
617: }
618: btinfo_modulelist->endpa = image_end;
1.41 jmcneill 619:
620: if (nfail > 0) {
621: printf("WARNING: %d module%s failed to load\n",
622: nfail, nfail == 1 ? "" : "s");
623: #if notyet
1.43 tsutsui 624: wait_sec(MODULE_WARNING_SEC);
1.41 jmcneill 625: #endif
626: }
1.23 ad 627: }
1.33 joerg 628:
1.47 uebayasi 629: static void
630: userconf_init(void)
631: {
632: size_t count, len;
633: userconf_command_t *uc;
634: char *buf;
635: off_t off;
636:
637: /* Calculate the userconf commands list size */
638: count = 0;
639: for (uc = userconf_commands; uc != NULL; uc = uc->uc_next)
640: count++;
1.55 jakllsch 641: len = sizeof(*btinfo_userconfcommands) +
1.47 uebayasi 642: count * sizeof(struct bi_userconfcommand);
643:
644: /* Allocate the userconf commands list */
645: btinfo_userconfcommands = alloc(len);
646: if (btinfo_userconfcommands == NULL) {
647: printf("WARNING: couldn't allocate userconf commands list\n");
648: return;
649: }
650: memset(btinfo_userconfcommands, 0, len);
651: btinfo_userconfcommands_size = len;
652:
653: /* Fill in btinfo structure */
654: buf = (char *)btinfo_userconfcommands;
655: off = sizeof(*btinfo_userconfcommands);
656: btinfo_userconfcommands->num = 0;
657: for (uc = userconf_commands; uc != NULL; uc = uc->uc_next) {
658: struct bi_userconfcommand *bi;
659: bi = (struct bi_userconfcommand *)(buf + off);
660: strncpy(bi->text, uc->uc_text, sizeof(bi->text) - 1);
661:
662: off += sizeof(*bi);
663: btinfo_userconfcommands->num++;
664: }
665: }
666:
1.33 joerg 667: int
668: exec_multiboot(const char *file, char *args)
669: {
670: struct multiboot_info *mbi;
671: struct multiboot_module *mbm;
672: struct bi_modulelist_entry *bim;
673: int i, len;
674: u_long marks[MARK_MAX];
675: u_long extmem;
676: u_long basemem;
677: char *cmdline;
678:
679: mbi = alloc(sizeof(struct multiboot_info));
680: mbi->mi_flags = MULTIBOOT_INFO_HAS_MEMORY;
681:
682: if (common_load_kernel(file, &basemem, &extmem, 0, 0, marks))
683: goto out;
684:
685: mbi->mi_mem_upper = extmem;
686: mbi->mi_mem_lower = basemem;
687:
688: if (args) {
689: mbi->mi_flags |= MULTIBOOT_INFO_HAS_CMDLINE;
690: len = strlen(file) + 1 + strlen(args) + 1;
691: cmdline = alloc(len);
692: snprintf(cmdline, len, "%s %s", file, args);
693: mbi->mi_cmdline = (char *) vtophys(cmdline);
694: }
695:
696: /* pull in any modules if necessary */
697: if (boot_modules_enabled) {
1.41 jmcneill 698: module_init(file);
1.33 joerg 699: if (btinfo_modulelist) {
700: mbm = alloc(sizeof(struct multiboot_module) *
701: btinfo_modulelist->num);
702:
703: bim = (struct bi_modulelist_entry *)
704: (((char *) btinfo_modulelist) +
705: sizeof(struct btinfo_modulelist));
706: for (i = 0; i < btinfo_modulelist->num; i++) {
707: mbm[i].mmo_start = bim->base;
708: mbm[i].mmo_end = bim->base + bim->len;
709: mbm[i].mmo_string = (char *)vtophys(bim->path);
710: mbm[i].mmo_reserved = 0;
711: bim++;
712: }
713: mbi->mi_flags |= MULTIBOOT_INFO_HAS_MODS;
714: mbi->mi_mods_count = btinfo_modulelist->num;
715: mbi->mi_mods_addr = vtophys(mbm);
716: }
717: }
718:
719: #ifdef DEBUG
720: printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
721: marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
722: #endif
723:
724:
725: #if 0
726: if (btinfo_symtab.nsym) {
727: mbi->mi_flags |= MULTIBOOT_INFO_HAS_ELF_SYMS;
728: mbi->mi_elfshdr_addr = marks[MARK_SYM];
729: btinfo_symtab.nsym = marks[MARK_NSYM];
730: btinfo_symtab.ssym = marks[MARK_SYM];
731: btinfo_symtab.esym = marks[MARK_END];
732: #endif
733:
734: multiboot(marks[MARK_ENTRY], vtophys(mbi),
735: x86_trunc_page(mbi->mi_mem_lower*1024));
736: panic("exec returned");
737:
738: out:
739: dealloc(mbi, 0);
740: return -1;
741: }
1.40 ad 742:
743: void
744: x86_progress(const char *fmt, ...)
745: {
746: va_list ap;
747:
748: if ((howto & AB_SILENT) != 0)
749: return;
750: va_start(ap, fmt);
751: vprintf(fmt, ap);
752: va_end(ap);
753: }
CVSweb <webmaster@jp.NetBSD.org>