[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     ! 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