[BACK]Return to exec.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / stand / lib

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>