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

Annotation of src/sys/arch/i386/stand/boot/boot2.c, Revision 1.47.2.1

1.47.2.1! uebayasi    1: /*     $NetBSD$        */
1.25      ad          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:  */
1.1       dsl        28:
                     29: /*
                     30:  * Copyright (c) 2003
                     31:  *     David Laight.  All rights reserved
                     32:  * Copyright (c) 1996, 1997, 1999
                     33:  *     Matthias Drochner.  All rights reserved.
                     34:  * Copyright (c) 1996, 1997
                     35:  *     Perry E. Metzger.  All rights reserved.
                     36:  * Copyright (c) 1997
                     37:  *     Jason R. Thorpe.  All rights reserved
                     38:  *
                     39:  * Redistribution and use in source and binary forms, with or without
                     40:  * modification, are permitted provided that the following conditions
                     41:  * are met:
                     42:  * 1. Redistributions of source code must retain the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer.
                     44:  * 2. Redistributions in binary form must reproduce the above copyright
                     45:  *    notice, this list of conditions and the following disclaimer in the
                     46:  *    documentation and/or other materials provided with the distribution.
                     47:  * 3. All advertising materials mentioning features or use of this software
                     48:  *    must display the following acknowledgements:
                     49:  *     This product includes software developed for the NetBSD Project
                     50:  *     by Matthias Drochner.
                     51:  *     This product includes software developed for the NetBSD Project
                     52:  *     by Perry E. Metzger.
                     53:  * 4. The names of the authors may not be used to endorse or promote products
                     54:  *    derived from this software without specific prior written permission.
                     55:  *
                     56:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     57:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     58:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     59:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     60:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     61:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     62:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     63:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     64:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     65:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     66:  */
                     67:
                     68: /* Based on stand/biosboot/main.c */
                     69:
1.5       christos   70: #include <sys/types.h>
1.1       dsl        71: #include <sys/reboot.h>
                     72: #include <sys/bootblock.h>
                     73:
                     74: #include <lib/libsa/stand.h>
                     75: #include <lib/libsa/ufs.h>
                     76: #include <lib/libkern/libkern.h>
                     77:
                     78: #include <libi386.h>
1.40      ad         79: #include <bootmod.h>
                     80: #include <bootmenu.h>
1.43      jmcneill   81: #include <vbe.h>
1.1       dsl        82: #include "devopen.h"
                     83:
                     84: #ifdef SUPPORT_PS2
                     85: #include <biosmca.h>
                     86: #endif
                     87:
1.4       lukem      88: extern struct x86_boot_params boot_params;
1.1       dsl        89:
1.32      perry      90: extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
1.1       dsl        91:
1.11      junyoung   92: int errno;
                     93:
                     94: int boot_biosdev;
                     95: u_int boot_biossector;
                     96:
1.1       dsl        97: static const char * const names[][2] = {
1.8       junyoung   98:        { "netbsd", "netbsd.gz" },
                     99:        { "onetbsd", "onetbsd.gz" },
                    100:        { "netbsd.old", "netbsd.old.gz" },
1.1       dsl       101: };
                    102:
                    103: #define NUMNAMES (sizeof(names)/sizeof(names[0]))
                    104: #define DEFFILENAME names[0][0]
                    105:
                    106: #define MAXDEVNAME 16
                    107:
                    108: static char *default_devname;
                    109: static int default_unit, default_partition;
                    110: static const char *default_filename;
                    111:
                    112: char *sprint_bootsel(const char *);
                    113: void bootit(const char *, int, int);
                    114: void print_banner(void);
1.11      junyoung  115: void boot2(int, u_int);
1.1       dsl       116:
                    117: void   command_help(char *);
                    118: void   command_ls(char *);
                    119: void   command_quit(char *);
                    120: void   command_boot(char *);
                    121: void   command_dev(char *);
                    122: void   command_consdev(char *);
1.25      ad        123: void   command_modules(char *);
1.38      joerg     124: void   command_multiboot(char *);
1.1       dsl       125:
                    126: const struct bootblk_command commands[] = {
                    127:        { "help",       command_help },
                    128:        { "?",          command_help },
                    129:        { "ls",         command_ls },
                    130:        { "quit",       command_quit },
                    131:        { "boot",       command_boot },
                    132:        { "dev",        command_dev },
                    133:        { "consdev",    command_consdev },
1.25      ad        134:        { "modules",    command_modules },
1.40      ad        135:        { "load",       module_add },
1.38      joerg     136:        { "multiboot",  command_multiboot },
1.43      jmcneill  137:        { "vesa",       command_vesa },
1.1       dsl       138:        { NULL,         NULL },
                    139: };
                    140:
                    141: int
                    142: parsebootfile(const char *fname, char **fsname, char **devname,
1.11      junyoung  143:              int *unit, int *partition, const char **file)
1.1       dsl       144: {
                    145:        const char *col;
                    146:
                    147:        *fsname = "ufs";
                    148:        *devname = default_devname;
                    149:        *unit = default_unit;
                    150:        *partition = default_partition;
                    151:        *file = default_filename;
                    152:
                    153:        if (fname == NULL)
1.7       junyoung  154:                return 0;
1.1       dsl       155:
1.8       junyoung  156:        if ((col = strchr(fname, ':')) != NULL) {       /* device given */
1.1       dsl       157:                static char savedevname[MAXDEVNAME+1];
                    158:                int devlen;
1.11      junyoung  159:                int u = 0, p = 0;
1.1       dsl       160:                int i = 0;
                    161:
                    162:                devlen = col - fname;
                    163:                if (devlen > MAXDEVNAME)
1.6       junyoung  164:                        return EINVAL;
1.1       dsl       165:
                    166: #define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
                    167:                if (!isvalidname(fname[i]))
1.6       junyoung  168:                        return EINVAL;
1.1       dsl       169:                do {
                    170:                        savedevname[i] = fname[i];
                    171:                        i++;
                    172:                } while (isvalidname(fname[i]));
                    173:                savedevname[i] = '\0';
                    174:
                    175: #define isnum(c) ((c) >= '0' && (c) <= '9')
                    176:                if (i < devlen) {
                    177:                        if (!isnum(fname[i]))
1.6       junyoung  178:                                return EUNIT;
1.1       dsl       179:                        do {
                    180:                                u *= 10;
                    181:                                u += fname[i++] - '0';
                    182:                        } while (isnum(fname[i]));
                    183:                }
                    184:
                    185: #define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
                    186:                if (i < devlen) {
                    187:                        if (!isvalidpart(fname[i]))
1.6       junyoung  188:                                return EPART;
1.1       dsl       189:                        p = fname[i++] - 'a';
                    190:                }
                    191:
                    192:                if (i != devlen)
1.6       junyoung  193:                        return ENXIO;
1.1       dsl       194:
                    195:                *devname = savedevname;
                    196:                *unit = u;
                    197:                *partition = p;
                    198:                fname = col + 1;
                    199:        }
                    200:
                    201:        if (*fname)
                    202:                *file = fname;
                    203:
1.6       junyoung  204:        return 0;
1.1       dsl       205: }
                    206:
                    207: char *
                    208: sprint_bootsel(const char *filename)
                    209: {
                    210:        char *fsname, *devname;
                    211:        int unit, partition;
                    212:        const char *file;
                    213:        static char buf[80];
                    214:
                    215:        if (parsebootfile(filename, &fsname, &devname, &unit,
                    216:                          &partition, &file) == 0) {
                    217:                sprintf(buf, "%s%d%c:%s", devname, unit, 'a' + partition, file);
1.6       junyoung  218:                return buf;
1.1       dsl       219:        }
1.6       junyoung  220:        return "(invalid)";
1.1       dsl       221: }
                    222:
1.44      ad        223: static void
                    224: clearit(void)
                    225: {
                    226:
                    227:        if (bootconf.clear)
                    228:                clear_pc_screen();
                    229: }
                    230:
1.1       dsl       231: void
                    232: bootit(const char *filename, int howto, int tell)
                    233: {
                    234:
                    235:        if (tell) {
                    236:                printf("booting %s", sprint_bootsel(filename));
                    237:                if (howto)
                    238:                        printf(" (howto 0x%x)", howto);
                    239:                printf("\n");
                    240:        }
                    241:
1.44      ad        242:        if (exec_netbsd(filename, 0, howto, boot_biosdev < 0x80, clearit) < 0)
1.1       dsl       243:                printf("boot: %s: %s\n", sprint_bootsel(filename),
                    244:                       strerror(errno));
                    245:        else
                    246:                printf("boot returned\n");
                    247: }
                    248:
                    249: void
                    250: print_banner(void)
                    251: {
1.41      christos  252:
1.44      ad        253:        clearit();
1.15      sborrill  254: #ifndef SMALL
                    255:        int n;
                    256:        if (bootconf.banner[0]) {
1.22      sborrill  257:                for (n = 0; bootconf.banner[n] && n < MAXBANNER; n++)
1.15      sborrill  258:                        printf("%s\n", bootconf.banner[n]);
                    259:        } else {
                    260: #endif /* !SMALL */
1.32      perry     261:                printf("\n"
                    262:                       ">> %s, Revision %s (from NetBSD %s)\n"
                    263:                       ">> Memory: %d/%d k\n",
                    264:                       bootprog_name, bootprog_rev, bootprog_kernrev,
                    265:                       getbasemem(), getextmem());
1.15      sborrill  266:
                    267: #ifndef SMALL
                    268:        }
                    269: #endif /* !SMALL */
                    270: }
                    271:
1.11      junyoung  272: /*
                    273:  * Called from the initial entry point boot_start in biosboot.S
                    274:  *
                    275:  * biosdev: BIOS drive number the system booted from
                    276:  * biossector: Sector number of the NetBSD partition
                    277:  */
1.1       dsl       278: void
1.11      junyoung  279: boot2(int biosdev, u_int biossector)
1.1       dsl       280: {
1.31      ad        281:        extern char twiddle_toggle;
1.1       dsl       282:        int currname;
                    283:        char c;
                    284:
1.31      ad        285:        twiddle_toggle = 1;     /* no twiddling until we're ready */
                    286:
1.1       dsl       287:        initio(boot_params.bp_consdev);
                    288:
                    289: #ifdef SUPPORT_PS2
                    290:        biosmca();
                    291: #endif
                    292:        gateA20();
                    293:
1.47      drochner  294:        boot_modules_enabled = !(boot_params.bp_flags
                    295:                                 & X86_BP_FLAGS_NOMODULES);
1.4       lukem     296:        if (boot_params.bp_flags & X86_BP_FLAGS_RESET_VIDEO)
1.1       dsl       297:                biosvideomode();
                    298:
1.43      jmcneill  299:        vbe_init();
                    300:
1.11      junyoung  301:        /* need to remember these */
                    302:        boot_biosdev = biosdev;
                    303:        boot_biossector = biossector;
                    304:
1.1       dsl       305:        /* try to set default device to what BIOS tells us */
1.11      junyoung  306:        bios2dev(biosdev, biossector, &default_devname, &default_unit,
                    307:                 &default_partition);
1.1       dsl       308:
                    309:        /* if the user types "boot" without filename */
                    310:        default_filename = DEFFILENAME;
                    311:
1.15      sborrill  312: #ifndef SMALL
1.47      drochner  313:        if (!(boot_params.bp_flags & X86_BP_FLAGS_NOBOOTCONF))
1.46      drochner  314:                parsebootconf(BOOTCONF);
1.15      sborrill  315:
                    316:        /*
1.20      sborrill  317:         * If console set in boot.cfg, switch to it.
1.15      sborrill  318:         * This will print the banner, so we don't need to explicitly do it
                    319:         */
                    320:        if (bootconf.consdev)
                    321:                command_consdev(bootconf.consdev);
                    322:        else
                    323:                print_banner();
                    324:
                    325:        /* Display the menu, if applicable */
1.31      ad        326:        twiddle_toggle = 0;
1.15      sborrill  327:        if (bootconf.nummenu > 0) {
                    328:                /* Does not return */
                    329:                doboottypemenu();
                    330:        }
1.43      jmcneill  331:
1.15      sborrill  332: #else
1.31      ad        333:        twiddle_toggle = 0;
                    334:        print_banner();
1.15      sborrill  335: #endif
                    336:
1.1       dsl       337:        printf("Press return to boot now, any other key for boot menu\n");
1.10      junyoung  338:        for (currname = 0; currname < NUMNAMES; currname++) {
1.1       dsl       339:                printf("booting %s - starting in ",
                    340:                       sprint_bootsel(names[currname][0]));
                    341:
1.15      sborrill  342: #ifdef SMALL
1.1       dsl       343:                c = awaitkey(boot_params.bp_timeout, 1);
1.15      sborrill  344: #else
                    345:                c = awaitkey((bootconf.timeout < 0) ? 0 : bootconf.timeout, 1);
                    346: #endif
1.47.2.1! uebayasi  347:                if ((c != '\r') && (c != '\n') && (c != '\0')) {
        !           348:                    if ((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0) {
        !           349:                        /* do NOT ask for password */
1.1       dsl       350:                        bootmenu(); /* does not return */
1.47.2.1! uebayasi  351:                    } else {
        !           352:                        /* DO ask for password */
        !           353:                        if (check_password(boot_params.bp_password)) {
        !           354:                            /* password ok */
        !           355:                            printf("type \"?\" or \"help\" for help.\n");
        !           356:                            bootmenu(); /* does not return */
        !           357:                        } else {
        !           358:                            /* bad password */
        !           359:                            printf("Wrong password.\n");
        !           360:                            currname = 0;
        !           361:                            continue;
        !           362:                        }
        !           363:                    }
1.1       dsl       364:                }
                    365:
                    366:                /*
                    367:                 * try pairs of names[] entries, foo and foo.gz
                    368:                 */
                    369:                /* don't print "booting..." again */
                    370:                bootit(names[currname][0], 0, 0);
                    371:                /* since it failed, try compressed bootfile. */
                    372:                bootit(names[currname][1], 0, 1);
                    373:        }
1.10      junyoung  374:
                    375:        bootmenu();     /* does not return */
1.1       dsl       376: }
                    377:
                    378: /* ARGSUSED */
                    379: void
                    380: command_help(char *arg)
                    381: {
                    382:
                    383:        printf("commands are:\n"
1.23      ad        384:               "boot [xdNx:][filename] [-12acdqsvxz]\n"
1.8       junyoung  385:               "     (ex. \"hd0a:netbsd.old -s\"\n"
                    386:               "ls [path]\n"
                    387:               "dev xd[N[x]]:\n"
                    388:               "consdev {pc|com[0123]|com[0123]kbd|auto}\n"
1.43      jmcneill  389:               "vesa {enabled|disabled|list|modenum}\n"
1.25      ad        390:               "modules {enabled|disabled}\n"
                    391:               "load {path_to_module}\n"
1.38      joerg     392:               "multiboot [xdNx:][filename] [<args>]\n"
1.8       junyoung  393:               "help|?\n"
                    394:               "quit\n");
1.1       dsl       395: }
                    396:
                    397: void
                    398: command_ls(char *arg)
                    399: {
                    400:        const char *save = default_filename;
                    401:
                    402:        default_filename = "/";
                    403:        ufs_ls(arg);
                    404:        default_filename = save;
                    405: }
                    406:
                    407: /* ARGSUSED */
                    408: void
                    409: command_quit(char *arg)
                    410: {
                    411:
                    412:        printf("Exiting...\n");
                    413:        delay(1000000);
                    414:        reboot();
                    415:        /* Note: we shouldn't get to this point! */
                    416:        panic("Could not reboot!");
                    417:        exit(0);
                    418: }
                    419:
                    420: void
                    421: command_boot(char *arg)
                    422: {
                    423:        char *filename;
                    424:        int howto;
                    425:
                    426:        if (parseboot(arg, &filename, &howto))
1.44      ad        427:                bootit(filename, howto, (howto & AB_VERBOSE) != 0);
1.1       dsl       428: }
                    429:
                    430: void
                    431: command_dev(char *arg)
                    432: {
                    433:        static char savedevname[MAXDEVNAME + 1];
                    434:        char *fsname, *devname;
                    435:        const char *file; /* dummy */
                    436:
                    437:        if (*arg == '\0') {
1.45      jmcneill  438:                biosdisk_probe();
                    439:                printf("default %s%d%c\n", default_devname, default_unit,
1.1       dsl       440:                       'a' + default_partition);
                    441:                return;
                    442:        }
                    443:
1.13      ws        444:        if (strchr(arg, ':') == NULL ||
1.1       dsl       445:            parsebootfile(arg, &fsname, &devname, &default_unit,
                    446:                          &default_partition, &file)) {
                    447:                command_help(NULL);
                    448:                return;
                    449:        }
                    450:
                    451:        /* put to own static storage */
                    452:        strncpy(savedevname, devname, MAXDEVNAME + 1);
                    453:        default_devname = savedevname;
                    454: }
                    455:
                    456: static const struct cons_devs {
1.8       junyoung  457:        const char      *name;
1.9       junyoung  458:        u_int           tag;
1.1       dsl       459: } cons_devs[] = {
                    460:        { "pc",         CONSDEV_PC },
                    461:        { "com0",       CONSDEV_COM0 },
                    462:        { "com1",       CONSDEV_COM1 },
                    463:        { "com2",       CONSDEV_COM2 },
                    464:        { "com3",       CONSDEV_COM3 },
                    465:        { "com0kbd",    CONSDEV_COM0KBD },
                    466:        { "com1kbd",    CONSDEV_COM1KBD },
                    467:        { "com2kbd",    CONSDEV_COM2KBD },
                    468:        { "com3kbd",    CONSDEV_COM3KBD },
                    469:        { "auto",       CONSDEV_AUTO },
1.8       junyoung  470:        { NULL,         0 }
                    471: };
1.1       dsl       472:
                    473: void
                    474: command_consdev(char *arg)
                    475: {
                    476:        const struct cons_devs *cdp;
                    477:
                    478:        for (cdp = cons_devs; cdp->name; cdp++) {
1.6       junyoung  479:                if (strcmp(arg, cdp->name) == 0) {
1.1       dsl       480:                        initio(cdp->tag);
                    481:                        print_banner();
                    482:                        return;
                    483:                }
                    484:        }
                    485:        printf("invalid console device.\n");
                    486: }
1.25      ad        487:
                    488: void
                    489: command_modules(char *arg)
                    490: {
                    491:
                    492:        if (strcmp(arg, "enabled") == 0 ||
                    493:            strcmp(arg, "on") == 0)
                    494:                boot_modules_enabled = true;
                    495:        else if (strcmp(arg, "disabled") == 0 ||
                    496:            strcmp(arg, "off") == 0)
                    497:                boot_modules_enabled = false;
                    498:        else
                    499:                printf("invalid flag, must be 'enabled' or 'disabled'.\n");
                    500: }
                    501:
                    502: void
1.38      joerg     503: command_multiboot(char *arg)
                    504: {
                    505:        char *filename;
                    506:
                    507:        filename = arg;
                    508:        if (exec_multiboot(filename, gettrailer(arg)) < 0)
                    509:                printf("multiboot: %s: %s\n", sprint_bootsel(filename),
                    510:                       strerror(errno));
                    511:        else
                    512:                printf("boot returned\n");
                    513: }
                    514:

CVSweb <webmaster@jp.NetBSD.org>