[BACK]Return to boot.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc64 / stand / ofwboot

Annotation of sys/arch/sparc64/stand/ofwboot/boot.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: boot.c,v 1.14 2007/05/29 00:03:13 deraadt Exp $       */
                      2: /*     $NetBSD: boot.c,v 1.3 2001/05/31 08:55:19 mrg Exp $     */
                      3: /*
                      4:  * Copyright (c) 1997, 1999 Eduardo E. Horvath.  All rights reserved.
                      5:  * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
                      6:  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
                      7:  * Copyright (C) 1995, 1996 TooLs GmbH.
                      8:  * All rights reserved.
                      9:  *
                     10:  * ELF support derived from NetBSD/alpha's boot loader, written
                     11:  * by Christopher G. Demetriou.
                     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 acknowledgement:
                     23:  *     This product includes software developed by TooLs GmbH.
                     24:  * 4. The name of TooLs GmbH may not be used to endorse or promote products
                     25:  *    derived from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
                     28:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     29:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     30:  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     31:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     32:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     33:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     34:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     35:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     36:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * First try for the boot code
                     41:  *
                     42:  * Input syntax is:
                     43:  *     [promdev[{:|,}partition]]/[filename] [flags]
                     44:  */
                     45:
                     46: #define ELFSIZE 64
                     47:
                     48: #include <lib/libsa/stand.h>
                     49:
                     50: #include <sys/param.h>
                     51: #include <sys/exec.h>
                     52: #include <sys/exec_elf.h>
                     53: #include <sys/reboot.h>
                     54: #include <sys/disklabel.h>
                     55: #include <machine/boot_flag.h>
                     56:
                     57: #include <machine/cpu.h>
                     58:
                     59: #include "ofdev.h"
                     60: #include "openfirm.h"
                     61:
                     62: #define        MEG     (1024*1024)
                     63:
                     64: /*
                     65:  * Boot device is derived from ROM provided information, or if there is none,
                     66:  * this list is used in sequence, to find a kernel.
                     67:  */
                     68: char *kernels[] = {
                     69:        "bsd",
                     70:        NULL
                     71: };
                     72:
                     73: char bootdev[128];
                     74: char bootfile[128];
                     75: int boothowto;
                     76: int debug;
                     77:
                     78:
                     79: #ifdef SPARC_BOOT_ELF
                     80: int    elf64_exec(int, Elf64_Ehdr *, u_int64_t *, void **, void **);
                     81: #endif
                     82:
                     83: #if 0
                     84: static void
                     85: prom2boot(dev)
                     86:        char *dev;
                     87: {
                     88:        char *cp, *lp = 0;
                     89:        int handle;
                     90:        char devtype[16];
                     91:
                     92:        for (cp = dev; *cp; cp++)
                     93:                if (*cp == ':')
                     94:                        lp = cp;
                     95:        if (!lp)
                     96:                lp = cp;
                     97:        *lp = 0;
                     98: }
                     99: #endif
                    100:
                    101: /*
                    102:  *     parse:
                    103:  *             [kernel-name] [-options]
                    104:  *     leave kernel-name in passed-in string
                    105:  *     put options into *howtop
                    106:  *     return -1 iff syntax error (no - before options)
                    107:  */
                    108:
                    109: static int
                    110: parseargs(str, howtop)
                    111:        char *str;
                    112:        int *howtop;
                    113: {
                    114:        char *cp;
                    115:        int i;
                    116:
                    117:        *howtop = 0;
                    118:        cp = str;
                    119:        while (*cp == ' ')
                    120:                ++cp;
                    121:        if (*cp != '-') {
                    122:                while (*cp && *cp != ' ')
                    123:                        *str++ = *cp++;
                    124:                while (*cp == ' ')
                    125:                        ++cp;
                    126:        }
                    127:        *str = 0;
                    128:        switch(*cp) {
                    129:        default:
                    130:                printf ("boot options string <%s> must start with -\n", cp);
                    131:                return -1;
                    132:        case 0:
                    133:                return 0;
                    134:        case '-':
                    135:                break;
                    136:        }
                    137:
                    138:        ++cp;
                    139:        while (*cp) {
                    140:                BOOT_FLAG(*cp, *howtop);
                    141:                /* handle specialties */
                    142:                switch (*cp++) {
                    143:                case 'd':
                    144:                        if (!debug) debug = 1;
                    145:                        break;
                    146:                case 'D':
                    147:                        debug = 2;
                    148:                        break;
                    149:                }
                    150:        }
                    151:        return 0;
                    152: }
                    153:
                    154:
                    155: static void
                    156: chain(pentry, args, ssym, esym)
                    157:        u_int64_t pentry;
                    158:        char *args;
                    159:        void *ssym;
                    160:        void *esym;
                    161: {
                    162:        extern char end[];
                    163:        void (*entry)();
                    164:        int l, machine_tag;
                    165:        long newargs[3];
                    166:
                    167:        entry = (void *)(long)pentry;
                    168:
                    169:        freeall();
                    170:        /*
                    171:         * When we come in args consists of a pointer to the boot
                    172:         * string.  We need to fix it so it takes into account
                    173:         * other params such as romp.
                    174:         */
                    175:
                    176:        /*
                    177:         * Stash pointer to end of symbol table after the argument
                    178:         * strings.
                    179:         */
                    180:        l = strlen(args) + 1;
                    181:        bcopy(&esym, args + l, sizeof(esym));
                    182:        l += sizeof(esym);
                    183:
                    184:        /*
                    185:         * Tell the kernel we're an OpenFirmware system.
                    186:         */
                    187: #define SPARC_MACHINE_OPENFIRMWARE             0x44444230
                    188:        machine_tag = SPARC_MACHINE_OPENFIRMWARE;
                    189:        bcopy(&machine_tag, args + l, sizeof(machine_tag));
                    190:        l += sizeof(machine_tag);
                    191:
                    192:        /*
                    193:         * Since we don't need the boot string (we can get it from /chosen)
                    194:         * we won't pass it in.  Just pass in esym and magic #
                    195:         */
                    196:        newargs[0] = SPARC_MACHINE_OPENFIRMWARE;
                    197:        newargs[1] = (long)esym;
                    198:        newargs[2] = (long)ssym;
                    199:        args = (char *)newargs;
                    200:        l = sizeof(newargs);
                    201:
                    202: #ifdef DEBUG
                    203:        printf("chain: calling OF_chain(%x, %x, %x, %x, %x)\n",
                    204:            (void *)RELOC, end - (char *)RELOC, entry, args, l);
                    205: #endif
                    206:        /* if -D is set then pause in the PROM. */
                    207:        if (debug > 1) OF_enter();
                    208:        OF_chain((void *)RELOC, ((end - (char *)RELOC)+NBPG)%NBPG, entry, args, l);
                    209:        panic("chain");
                    210: }
                    211:
                    212: int
                    213: loadfile(fd, args)
                    214:        int fd;
                    215:        char *args;
                    216: {
                    217:        union {
                    218: #ifdef SPARC_BOOT_ELF
                    219:                Elf64_Ehdr elf64;
                    220: #endif
                    221:        } hdr;
                    222:        int rval;
                    223:        u_int64_t entry = 0;
                    224:        void *ssym;
                    225:        void *esym;
                    226:
                    227:        ssym = NULL;
                    228:        esym = NULL;
                    229:
                    230:        /* Load the header. */
                    231: #ifdef DEBUG
                    232:        printf("loadfile: reading header\n");
                    233: #endif
                    234:        if ((rval = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
                    235:                if (rval == -1)
                    236:                        printf("read header: %s\n", strerror(errno));
                    237:                else
                    238:                        printf("read header: short read (only %d of %d)\n",
                    239:                            rval, sizeof(hdr));
                    240:                rval = 1;
                    241:                goto err;
                    242:        }
                    243:
                    244:        /* Determine file type, load kernel. */
                    245: #ifdef SPARC_BOOT_ELF
                    246:        if (bcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
                    247:            hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
                    248:                rval = elf64_exec(fd, &hdr.elf64, &entry, &ssym, &esym);
                    249:        } else
                    250: #endif
                    251:        {
                    252:                rval = 1;
                    253:                printf("unknown executable format\n");
                    254:        }
                    255:
                    256:        if (rval)
                    257:                goto err;
                    258:
                    259:        printf(" start=0x%lx\n", (unsigned long)entry);
                    260:
                    261:        close(fd);
                    262:
                    263:        chain(entry, args, ssym, esym);
                    264:        /* NOTREACHED */
                    265:
                    266:  err:
                    267:        close(fd);
                    268:        return (rval);
                    269: }
                    270:
                    271: #ifdef SPARC_BOOT_ELF
                    272: #include "elfXX_exec.c"
                    273: #endif /* SPARC_BOOT_ELF */
                    274:
                    275: int
                    276: main()
                    277: {
                    278:        extern char version[];
                    279:        int chosen;
                    280:        char bootline[512];             /* Should check size? */
                    281:        char *cp;
                    282:        int i, fd;
                    283:        char **bootlp;
                    284:        char *just_bootline[2];
                    285:
                    286:        printf(">> OpenBSD BOOT %s\n", version);
                    287:
                    288:        /*
                    289:         * Get the boot arguments from Openfirmware
                    290:         */
                    291:        if ((chosen = OF_finddevice("/chosen")) == -1 ||
                    292:            OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 ||
                    293:            OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
                    294:                printf("Invalid Openfirmware environment\n");
                    295:                exit();
                    296:        }
                    297:
                    298:        /*
                    299:         * case 1:      boot net -a
                    300:         *                      -> gets loop
                    301:         * case 2:      boot net kernel [options]
                    302:         *                      -> boot kernel, gets loop
                    303:         * case 3:      boot net [options]
                    304:         *                      -> iterate boot list, gets loop
                    305:         */
                    306:
                    307:        bootlp = kernels;
                    308:        if (parseargs(bootline, &boothowto) == -1 ||
                    309:            (boothowto & RB_ASKNAME)) {
                    310:                bootlp = 0;
                    311:        } else if (*bootline) {
                    312:                just_bootline[0] = bootline;
                    313:                just_bootline[1] = 0;
                    314:                bootlp = just_bootline;
                    315:        }
                    316:        for (;;) {
                    317:                if (bootlp) {
                    318:                        cp = *bootlp++;
                    319:                        if (!cp) {
                    320:                                printf("\n");
                    321:                                bootlp = 0;
                    322:                                kernels[0] = 0; /* no more iteration */
                    323:                        } else if (cp != bootline) {
                    324:                                printf("Trying %s...\n", cp);
                    325:                                strlcpy(bootline, cp, sizeof bootline);
                    326:                        }
                    327:                }
                    328:                if (!bootlp) {
                    329:                        printf("Boot: ");
                    330:                        gets(bootline);
                    331:                        if (parseargs(bootline, &boothowto) == -1)
                    332:                                continue;
                    333:                        if (!*bootline) {
                    334:                                bootlp = kernels;
                    335:                                continue;
                    336:                        }
                    337:                        if (strcmp(bootline, "exit") == 0 ||
                    338:                            strcmp(bootline, "halt") == 0) {
                    339:                                _rtt();
                    340:                        }
                    341:                }
                    342:                if ((fd = open(bootline, 0)) < 0) {
                    343:                        printf("open %s: %s\n", opened_name, strerror(errno));
                    344:                        continue;
                    345:                }
                    346: #ifdef __notyet__
                    347:                OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
                    348:                cp = bootline;
                    349: #else
                    350:                strlcpy(bootline, opened_name, sizeof bootline);
                    351:                cp = bootline + strlen(bootline);
                    352:                *cp++ = ' ';
                    353: #endif
                    354:                *cp = '-';
                    355:                if (boothowto & RB_ASKNAME)
                    356:                        *++cp = 'a';
                    357:                if (boothowto & RB_SINGLE)
                    358:                        *++cp = 's';
                    359:                if (boothowto & RB_KDB)
                    360:                        *++cp = 'd';
                    361:                if (*cp == '-')
                    362:                        *--cp = 0;
                    363:                else
                    364:                        *++cp = 0;
                    365: #ifdef __notyet__
                    366:                OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
                    367: #endif
                    368:                /* XXX void, for now */
                    369: #ifdef DEBUG
                    370:                if (debug)
                    371:                        printf("main: Calling loadfile(fd, %s)\n", bootline);
                    372: #endif
                    373:                (void)loadfile(fd, bootline);
                    374:        }
                    375:        return 0;
                    376: }

CVSweb