[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.21

1.21    ! apb         1: /*     $NetBSD: boot2.c,v 1.20 2008/01/02 10:39:39 sborrill Exp $      */
1.1       dsl         2:
                      3: /*
                      4:  * Copyright (c) 2003
                      5:  *     David Laight.  All rights reserved
                      6:  * Copyright (c) 1996, 1997, 1999
                      7:  *     Matthias Drochner.  All rights reserved.
                      8:  * Copyright (c) 1996, 1997
                      9:  *     Perry E. Metzger.  All rights reserved.
                     10:  * Copyright (c) 1997
                     11:  *     Jason R. Thorpe.  All rights reserved
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. All advertising materials mentioning features or use of this software
                     22:  *    must display the following acknowledgements:
                     23:  *     This product includes software developed for the NetBSD Project
                     24:  *     by Matthias Drochner.
                     25:  *     This product includes software developed for the NetBSD Project
                     26:  *     by Perry E. Metzger.
                     27:  * 4. The names of the authors may not be used to endorse or promote products
                     28:  *    derived from this software without specific prior written permission.
                     29:  *
                     30:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     31:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     32:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     33:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     34:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     35:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     36:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     37:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     38:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     39:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     40:  */
                     41:
                     42: /* Based on stand/biosboot/main.c */
                     43:
1.5       christos   44: #include <sys/types.h>
1.1       dsl        45: #include <sys/reboot.h>
                     46: #include <sys/bootblock.h>
                     47:
                     48: #include <lib/libsa/stand.h>
                     49: #include <lib/libsa/ufs.h>
                     50: #include <lib/libkern/libkern.h>
                     51:
                     52: #include <libi386.h>
                     53: #include "devopen.h"
                     54:
1.17      sborrill   55: #ifdef SUPPORT_USTARFS
                     56: #include "ustarfs.h"
                     57: #endif
1.1       dsl        58: #ifdef SUPPORT_PS2
                     59: #include <biosmca.h>
                     60: #endif
                     61:
1.4       lukem      62: extern struct x86_boot_params boot_params;
1.1       dsl        63:
                     64: extern const char bootprog_name[], bootprog_rev[], bootprog_date[],
                     65:        bootprog_maker[];
                     66:
1.11      junyoung   67: int errno;
                     68:
                     69: int boot_biosdev;
                     70: u_int boot_biossector;
                     71:
1.1       dsl        72: static const char * const names[][2] = {
1.8       junyoung   73:        { "netbsd", "netbsd.gz" },
                     74:        { "onetbsd", "onetbsd.gz" },
                     75:        { "netbsd.old", "netbsd.old.gz" },
1.1       dsl        76: };
                     77:
                     78: #define NUMNAMES (sizeof(names)/sizeof(names[0]))
                     79: #define DEFFILENAME names[0][0]
                     80:
                     81: #define MAXDEVNAME 16
                     82:
1.15      sborrill   83: #ifndef SMALL
                     84: #define BOOTCONF "boot.cfg"
                     85: #define MAXMENU 10
                     86: #define MAXBANNER 10
                     87: #endif /* !SMALL */
                     88:
1.1       dsl        89: static char *default_devname;
                     90: static int default_unit, default_partition;
                     91: static const char *default_filename;
                     92:
                     93: char *sprint_bootsel(const char *);
                     94: void bootit(const char *, int, int);
                     95: void print_banner(void);
1.11      junyoung   96: void boot2(int, u_int);
1.1       dsl        97:
1.15      sborrill   98: #ifndef SMALL
                     99: void parsebootconf(const char *);
                    100: void doboottypemenu(void);
                    101: int atoi(const char *);
                    102: #endif /* !SMALL */
                    103:
1.1       dsl       104: void   command_help(char *);
                    105: void   command_ls(char *);
                    106: void   command_quit(char *);
                    107: void   command_boot(char *);
                    108: void   command_dev(char *);
                    109: void   command_consdev(char *);
                    110:
                    111: const struct bootblk_command commands[] = {
                    112:        { "help",       command_help },
                    113:        { "?",          command_help },
                    114:        { "ls",         command_ls },
                    115:        { "quit",       command_quit },
                    116:        { "boot",       command_boot },
                    117:        { "dev",        command_dev },
                    118:        { "consdev",    command_consdev },
                    119:        { NULL,         NULL },
                    120: };
                    121:
1.15      sborrill  122: #ifndef SMALL
                    123: struct bootconf_def {
                    124:        char *banner[MAXBANNER];        /* Banner text */
                    125:        char *command[MAXMENU];         /* Menu commands per entry*/
                    126:        char *consdev;                  /* Console device */
                    127:        int def;                        /* Default menu option */
                    128:        char *desc[MAXMENU];            /* Menu text per entry */
                    129:        int nummenu;                    /* Number of menu items */
                    130:        int timeout;                    /* Timeout in seconds */
                    131: } bootconf;
                    132: #endif /* !SMALL */
                    133:
1.1       dsl       134: int
                    135: parsebootfile(const char *fname, char **fsname, char **devname,
1.11      junyoung  136:              int *unit, int *partition, const char **file)
1.1       dsl       137: {
                    138:        const char *col;
                    139:
                    140:        *fsname = "ufs";
                    141:        *devname = default_devname;
                    142:        *unit = default_unit;
                    143:        *partition = default_partition;
                    144:        *file = default_filename;
                    145:
                    146:        if (fname == NULL)
1.7       junyoung  147:                return 0;
1.1       dsl       148:
1.8       junyoung  149:        if ((col = strchr(fname, ':')) != NULL) {       /* device given */
1.1       dsl       150:                static char savedevname[MAXDEVNAME+1];
                    151:                int devlen;
1.11      junyoung  152:                int u = 0, p = 0;
1.1       dsl       153:                int i = 0;
                    154:
                    155:                devlen = col - fname;
                    156:                if (devlen > MAXDEVNAME)
1.6       junyoung  157:                        return EINVAL;
1.1       dsl       158:
                    159: #define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
                    160:                if (!isvalidname(fname[i]))
1.6       junyoung  161:                        return EINVAL;
1.1       dsl       162:                do {
                    163:                        savedevname[i] = fname[i];
                    164:                        i++;
                    165:                } while (isvalidname(fname[i]));
                    166:                savedevname[i] = '\0';
                    167:
                    168: #define isnum(c) ((c) >= '0' && (c) <= '9')
                    169:                if (i < devlen) {
                    170:                        if (!isnum(fname[i]))
1.6       junyoung  171:                                return EUNIT;
1.1       dsl       172:                        do {
                    173:                                u *= 10;
                    174:                                u += fname[i++] - '0';
                    175:                        } while (isnum(fname[i]));
                    176:                }
                    177:
                    178: #define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
                    179:                if (i < devlen) {
                    180:                        if (!isvalidpart(fname[i]))
1.6       junyoung  181:                                return EPART;
1.1       dsl       182:                        p = fname[i++] - 'a';
                    183:                }
                    184:
                    185:                if (i != devlen)
1.6       junyoung  186:                        return ENXIO;
1.1       dsl       187:
                    188:                *devname = savedevname;
                    189:                *unit = u;
                    190:                *partition = p;
                    191:                fname = col + 1;
                    192:        }
                    193:
                    194:        if (*fname)
                    195:                *file = fname;
                    196:
1.6       junyoung  197:        return 0;
1.1       dsl       198: }
                    199:
                    200: char *
                    201: sprint_bootsel(const char *filename)
                    202: {
                    203:        char *fsname, *devname;
                    204:        int unit, partition;
                    205:        const char *file;
                    206:        static char buf[80];
                    207:
                    208:        if (parsebootfile(filename, &fsname, &devname, &unit,
                    209:                          &partition, &file) == 0) {
                    210:                sprintf(buf, "%s%d%c:%s", devname, unit, 'a' + partition, file);
1.6       junyoung  211:                return buf;
1.1       dsl       212:        }
1.6       junyoung  213:        return "(invalid)";
1.1       dsl       214: }
                    215:
                    216: void
                    217: bootit(const char *filename, int howto, int tell)
                    218: {
                    219:
                    220:        if (tell) {
                    221:                printf("booting %s", sprint_bootsel(filename));
                    222:                if (howto)
                    223:                        printf(" (howto 0x%x)", howto);
                    224:                printf("\n");
                    225:        }
                    226:
                    227:        if (exec_netbsd(filename, 0, howto) < 0)
                    228:                printf("boot: %s: %s\n", sprint_bootsel(filename),
                    229:                       strerror(errno));
                    230:        else
                    231:                printf("boot returned\n");
                    232: }
                    233:
                    234: void
                    235: print_banner(void)
                    236: {
1.15      sborrill  237: #ifndef SMALL
                    238:        int n;
                    239:        if (bootconf.banner[0]) {
                    240:                for (n = 0; bootconf.banner[n]; n++)
                    241:                        printf("%s\n", bootconf.banner[n]);
                    242:        } else {
                    243: #endif /* !SMALL */
                    244:                printf("\n");
                    245:                printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
                    246:                printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
                    247:                printf(">> Memory: %d/%d k\n", getbasemem(), getextmem());
                    248:
                    249: #ifndef SMALL
                    250:        }
                    251: #endif /* !SMALL */
                    252: }
                    253:
                    254: #ifndef SMALL
                    255: int
                    256: atoi(const char *in)
                    257: {
                    258:        char *c;
                    259:        int ret;
                    260:
                    261:        ret = 0;
                    262:        c = (char *)in;
                    263:        if (*c == '-')
                    264:                c++;
                    265:        for (; isnum(*c); c++)
                    266:                ret = (ret * 10) + (*c - '0');
                    267:
                    268:        return (*in == '-') ? -ret : ret;
                    269: }
                    270:
                    271: /*
1.20      sborrill  272:  * This function parses a boot.cfg file in the root of the filesystem
1.15      sborrill  273:  * (if present) and populates the global boot configuration.
                    274:  *
                    275:  * The file consists of a number of lines each terminated by \n
                    276:  * The lines are in the format keyword=value. There should be spaces
                    277:  * around the = sign.
                    278:  *
                    279:  * The recognised keywords are:
                    280:  * banner: text displayed instead of the normal welcome text
                    281:  * menu: Descriptive text:command to use
                    282:  * timeout: Timeout in seconds (overrides that set by installboot)
                    283:  * default: the default menu option to use if Return is pressed
                    284:  * consdev: the console device to use
                    285:  *
1.20      sborrill  286:  * Example boot.cfg file:
1.15      sborrill  287:  * banner=Welcome to NetBSD
                    288:  * banner=Please choose the boot type from the following menu
                    289:  * menu=Boot NetBSD:boot netbsd
                    290:  * menu=Boot into single user mode:boot netbsd -s
1.21    ! apb       291:  * menu=:boot hd1a:netbsd -cs
1.15      sborrill  292:  * menu=Goto boot comand line:prompt
                    293:  * timeout=10
                    294:  * consdev=com0
                    295:  * default=1
                    296: */
                    297: void
                    298: parsebootconf(const char *conf)
                    299: {
                    300:        char *bc, *c;
                    301:        int cmenu, cbanner, len;
                    302:        int fd, err, off;
                    303:        struct stat st;
1.21    ! apb       304:        char *key, *value, *v2;
1.17      sborrill  305: #ifdef SUPPORT_USTARFS
                    306:        void *op_open;
                    307: #endif
1.15      sborrill  308:
                    309:        /* Clear bootconf structure */
                    310:        bzero((void *)&bootconf, sizeof(bootconf));
                    311:
                    312:        /* Set timeout to configured */
                    313:        bootconf.timeout = boot_params.bp_timeout;
                    314:
1.17      sborrill  315:        /* don't try to open BOOTCONF if the target fs is ustarfs */
                    316: #ifdef SUPPORT_USTARFS
                    317: #if !defined(LIBSA_SINGLE_FILESYSTEM)
                    318:        fd = open("boot", 0);   /* assume we are loaded as "boot" from here */
                    319:        if (fd < 0)
                    320:                op_open = NULL; /* XXX */
                    321:        else {
                    322:                op_open = files[fd].f_ops->open;
                    323:                close(fd);
                    324:        }
                    325: #else
                    326:        op_open = file_system[0].open;
                    327: #endif /* !LIBSA_SINGLE_FILESYSTEM */
                    328:        if (op_open == ustarfs_open)
1.15      sborrill  329:                return;
1.17      sborrill  330: #endif /* SUPPORT_USTARFS */
1.1       dsl       331:
1.15      sborrill  332:        fd = open(BOOTCONF, 0);
                    333:        if (fd < 0)
                    334:                return;
                    335:
1.17      sborrill  336:        err = fstat(fd, &st);
                    337:        if (err == -1) {
                    338:                close(fd);
                    339:                return;
                    340:        }
                    341:
1.15      sborrill  342:        bc = alloc(st.st_size + 1);
                    343:        if (bc == NULL) {
                    344:                printf("Could not allocate memory for boot configuration\n");
                    345:                return;
                    346:        }
                    347:
                    348:        off = 0;
                    349:        do {
                    350:                len = read(fd, bc + off, 1024);
                    351:                if (len <= 0)
                    352:                        break;
                    353:                off += len;
                    354:        } while (len > 0);
                    355:        bc[off] = '\0';
                    356:
                    357:        close(fd);
1.20      sborrill  358:        /* bc now contains the whole boot.cfg file */
1.15      sborrill  359:
                    360:        cmenu = 0;
                    361:        cbanner = 0;
                    362:        for(c = bc; *c; c++) {
                    363:                key = c;
                    364:                /* Look for = separator between key and value */
                    365:                for (; *c && *c != '='; c++)
                    366:                        continue;
                    367:                if (*c == '\0')
                    368:                        break; /* break if at end of data */
                    369:
                    370:                /* zero terminate key which points to keyword */
                    371:                *c++ = 0;
                    372:                value = c;
                    373:                /* Look for end of line (or file) and zero terminate value */
                    374:                for (; *c && *c != '\n'; c++)
                    375:                        continue;
                    376:                *c = 0;
                    377:
                    378:                if (!strncmp(key, "menu", 4)) {
1.21    ! apb       379:                        /*
        !           380:                         * Parse "menu=<description>:<command>".  If the
        !           381:                         * description is empty ("menu=:<command>)",
        !           382:                         * then re-use the command as the description.
        !           383:                         * Note that the command may contain embedded
        !           384:                         * colons.
        !           385:                         */
1.15      sborrill  386:                        if (cmenu >= MAXMENU)
                    387:                                continue;
                    388:                        bootconf.desc[cmenu] = value;
1.21    ! apb       389:                        for (v2=value; *v2 && *v2 != ':'; v2++)
1.15      sborrill  390:                                continue;
1.21    ! apb       391:                        if (*v2) {
        !           392:                                *v2++ = 0;
        !           393:                                bootconf.command[cmenu] = v2;
        !           394:                                if (! *value)
        !           395:                                        bootconf.desc[cmenu] = v2;
1.15      sborrill  396:                                cmenu++;
                    397:                        } else {
                    398:                                /* No delimiter means invalid line */
                    399:                                bootconf.desc[cmenu] = NULL;
                    400:                        }
                    401:                } else if (!strncmp(key, "banner", 6)) {
                    402:                        if (cbanner < MAXBANNER)
                    403:                                bootconf.banner[cbanner++] = value;
                    404:                } else if (!strncmp(key, "timeout", 7)) {
                    405:                        if (!isnum(*value))
                    406:                                bootconf.timeout = -1;
                    407:                        else
                    408:                                bootconf.timeout = atoi(value);
                    409:                } else if (!strncmp(key, "default", 7)) {
                    410:                        bootconf.def = atoi(value) - 1;
                    411:                } else if (!strncmp(key, "consdev", 7)) {
                    412:                        bootconf.consdev = value;
                    413:                }
                    414:        }
                    415:        bootconf.nummenu = cmenu;
                    416:        if (bootconf.def < 0)
                    417:                bootconf.def = 0;
                    418:        if (bootconf.def >= cmenu)
                    419:                bootconf.def = cmenu - 1;
                    420: }
                    421:
                    422: /*
                    423:  * doboottypemenu will render the menu and parse any user input
                    424:  */
                    425:
                    426: void
                    427: doboottypemenu(void)
                    428: {
                    429:        int choice;
                    430:        char input[80], c;
                    431:
1.16      sborrill  432:        printf("\n");
1.15      sborrill  433:        /* Display menu */
                    434:        for (choice = 0; bootconf.desc[choice]; choice++)
                    435:                printf("    %d. %s\n", choice+1, bootconf.desc[choice]);
                    436:
                    437:        choice = -1;
                    438:        for(;;) {
                    439:                input[0] = '\0';
                    440:
                    441:                if (bootconf.timeout < 0) {
                    442:                        printf("\nOption: [%d]:", bootconf.def + 1);
                    443:                        gets(input);
                    444:                        if (input[0] == '\0') choice = bootconf.def;
                    445:                        if (input[0] >= '1' &&
                    446:                                input[0] <= bootconf.nummenu + '0')
                    447:                                    choice = input[0] - '1';
                    448:                } else if (bootconf.timeout == 0)
                    449:                        choice = bootconf.def;
                    450:                else  {
                    451:                        printf("\nPress the key for your chosen option or ");
                    452:                        printf("Return to choose the default (%d)\n",
                    453:                              bootconf.def + 1);
                    454:                        printf("Option %d will be chosen in ",
                    455:                              bootconf.def + 1);
                    456:                        c = awaitkey(bootconf.timeout, 1);
                    457:                        if (c >= '1' && c <= bootconf.nummenu + '0')
                    458:                                choice = c - '1';
                    459:                        else if (c ==  '\r' || c == '\n' || c == '\0')
                    460:                                /* default if timed out or Return pressed */
                    461:                                choice = bootconf.def;
                    462:                        else {
                    463:                                /* If any other key pressed, drop to menu */
                    464:                                bootconf.timeout = -1;
                    465:                                choice = -1;
                    466:                        }
                    467:                }
                    468:                if (choice < 0)
                    469:                        continue;
                    470:                if (!strcmp(bootconf.command[choice], "prompt") &&
                    471:                    ((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0 ||
                    472:                    check_password(boot_params.bp_password))) {
                    473:                        printf("type \"?\" or \"help\" for help.\n");
                    474:                        bootmenu(); /* does not return */
                    475:                } else
                    476:                        docommand(bootconf.command[choice]);
                    477:
                    478:        }
1.1       dsl       479: }
1.15      sborrill  480: #endif /* !SMALL */
1.1       dsl       481:
1.11      junyoung  482: /*
                    483:  * Called from the initial entry point boot_start in biosboot.S
                    484:  *
                    485:  * biosdev: BIOS drive number the system booted from
                    486:  * biossector: Sector number of the NetBSD partition
                    487:  */
1.1       dsl       488: void
1.11      junyoung  489: boot2(int biosdev, u_int biossector)
1.1       dsl       490: {
                    491:        int currname;
                    492:        char c;
                    493:
                    494:        initio(boot_params.bp_consdev);
                    495:
                    496: #ifdef SUPPORT_PS2
                    497:        biosmca();
                    498: #endif
                    499:        gateA20();
                    500:
1.4       lukem     501:        if (boot_params.bp_flags & X86_BP_FLAGS_RESET_VIDEO)
1.1       dsl       502:                biosvideomode();
                    503:
1.11      junyoung  504:        /* need to remember these */
                    505:        boot_biosdev = biosdev;
                    506:        boot_biossector = biossector;
                    507:
1.1       dsl       508:        /* try to set default device to what BIOS tells us */
1.11      junyoung  509:        bios2dev(biosdev, biossector, &default_devname, &default_unit,
                    510:                 &default_partition);
1.1       dsl       511:
                    512:        /* if the user types "boot" without filename */
                    513:        default_filename = DEFFILENAME;
                    514:
1.15      sborrill  515: #ifndef SMALL
                    516:        parsebootconf(BOOTCONF);
                    517:
                    518:        /*
1.20      sborrill  519:         * If console set in boot.cfg, switch to it.
1.15      sborrill  520:         * This will print the banner, so we don't need to explicitly do it
                    521:         */
                    522:        if (bootconf.consdev)
                    523:                command_consdev(bootconf.consdev);
                    524:        else
                    525:                print_banner();
                    526:
                    527:        /* Display the menu, if applicable */
                    528:        if (bootconf.nummenu > 0) {
                    529:                /* Does not return */
                    530:                doboottypemenu();
                    531:        }
                    532: #else
                    533:                print_banner();
                    534: #endif
                    535:
1.1       dsl       536:        printf("Press return to boot now, any other key for boot menu\n");
1.10      junyoung  537:        for (currname = 0; currname < NUMNAMES; currname++) {
1.1       dsl       538:                printf("booting %s - starting in ",
                    539:                       sprint_bootsel(names[currname][0]));
                    540:
1.15      sborrill  541: #ifdef SMALL
1.1       dsl       542:                c = awaitkey(boot_params.bp_timeout, 1);
1.15      sborrill  543: #else
                    544:                c = awaitkey((bootconf.timeout < 0) ? 0 : bootconf.timeout, 1);
                    545: #endif
1.1       dsl       546:                if ((c != '\r') && (c != '\n') && (c != '\0') &&
1.4       lukem     547:                    ((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0
1.9       junyoung  548:                     || check_password(boot_params.bp_password))) {
1.1       dsl       549:                        printf("type \"?\" or \"help\" for help.\n");
                    550:                        bootmenu(); /* does not return */
                    551:                }
                    552:
                    553:                /*
                    554:                 * try pairs of names[] entries, foo and foo.gz
                    555:                 */
                    556:                /* don't print "booting..." again */
                    557:                bootit(names[currname][0], 0, 0);
                    558:                /* since it failed, try compressed bootfile. */
                    559:                bootit(names[currname][1], 0, 1);
                    560:        }
1.10      junyoung  561:
                    562:        bootmenu();     /* does not return */
1.1       dsl       563: }
                    564:
                    565: /* ARGSUSED */
                    566: void
                    567: command_help(char *arg)
                    568: {
                    569:
                    570:        printf("commands are:\n"
1.19      jmcneill  571:               "boot [xdNx:][filename] [-acdqsvxz]\n"
1.8       junyoung  572:               "     (ex. \"hd0a:netbsd.old -s\"\n"
                    573:               "ls [path]\n"
                    574:               "dev xd[N[x]]:\n"
                    575:               "consdev {pc|com[0123]|com[0123]kbd|auto}\n"
                    576:               "help|?\n"
                    577:               "quit\n");
1.1       dsl       578: }
                    579:
                    580: void
                    581: command_ls(char *arg)
                    582: {
                    583:        const char *save = default_filename;
                    584:
                    585:        default_filename = "/";
                    586:        ufs_ls(arg);
                    587:        default_filename = save;
                    588: }
                    589:
                    590: /* ARGSUSED */
                    591: void
                    592: command_quit(char *arg)
                    593: {
                    594:
                    595:        printf("Exiting...\n");
                    596:        delay(1000000);
                    597:        reboot();
                    598:        /* Note: we shouldn't get to this point! */
                    599:        panic("Could not reboot!");
                    600:        exit(0);
                    601: }
                    602:
                    603: void
                    604: command_boot(char *arg)
                    605: {
                    606:        char *filename;
                    607:        int howto;
                    608:
                    609:        if (parseboot(arg, &filename, &howto))
                    610:                bootit(filename, howto, 1);
                    611: }
                    612:
                    613: void
                    614: command_dev(char *arg)
                    615: {
                    616:        static char savedevname[MAXDEVNAME + 1];
                    617:        char *fsname, *devname;
                    618:        const char *file; /* dummy */
                    619:
                    620:        if (*arg == '\0') {
                    621:                printf("%s%d%c:\n", default_devname, default_unit,
                    622:                       'a' + default_partition);
                    623:                return;
                    624:        }
                    625:
1.13      ws        626:        if (strchr(arg, ':') == NULL ||
1.1       dsl       627:            parsebootfile(arg, &fsname, &devname, &default_unit,
                    628:                          &default_partition, &file)) {
                    629:                command_help(NULL);
                    630:                return;
                    631:        }
                    632:
                    633:        /* put to own static storage */
                    634:        strncpy(savedevname, devname, MAXDEVNAME + 1);
                    635:        default_devname = savedevname;
                    636: }
                    637:
                    638: static const struct cons_devs {
1.8       junyoung  639:        const char      *name;
1.9       junyoung  640:        u_int           tag;
1.1       dsl       641: } cons_devs[] = {
                    642:        { "pc",         CONSDEV_PC },
                    643:        { "com0",       CONSDEV_COM0 },
                    644:        { "com1",       CONSDEV_COM1 },
                    645:        { "com2",       CONSDEV_COM2 },
                    646:        { "com3",       CONSDEV_COM3 },
                    647:        { "com0kbd",    CONSDEV_COM0KBD },
                    648:        { "com1kbd",    CONSDEV_COM1KBD },
                    649:        { "com2kbd",    CONSDEV_COM2KBD },
                    650:        { "com3kbd",    CONSDEV_COM3KBD },
                    651:        { "auto",       CONSDEV_AUTO },
1.8       junyoung  652:        { NULL,         0 }
                    653: };
1.1       dsl       654:
                    655: void
                    656: command_consdev(char *arg)
                    657: {
                    658:        const struct cons_devs *cdp;
                    659:
                    660:        for (cdp = cons_devs; cdp->name; cdp++) {
1.6       junyoung  661:                if (strcmp(arg, cdp->name) == 0) {
1.1       dsl       662:                        initio(cdp->tag);
                    663:                        print_banner();
                    664:                        return;
                    665:                }
                    666:        }
                    667:        printf("invalid console device.\n");
                    668: }

CVSweb <webmaster@jp.NetBSD.org>