[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / prex / boot / common

Annotation of prex/boot/common/main.c, Revision 1.1

1.1     ! nbrk        1: /*-
        !             2:  * Copyright (c) 2005-2006, Kohsuke Ohtani
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. Neither the name of the author nor the names of any co-contributors
        !            14:  *    may be used to endorse or promote products derived from this software
        !            15:  *    without specific prior written permission.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            27:  * SUCH DAMAGE.
        !            28:  */
        !            29:
        !            30: /*
        !            31:  * main.c - Prex boot loader main module
        !            32:  */
        !            33:
        !            34: #include <prex/bootinfo.h>
        !            35: #include <platform.h>
        !            36: #include <boot.h>
        !            37: #include <ar.h>
        !            38:
        !            39: #ifdef DEBUG
        !            40: #define DPRINTF(a) printf a
        !            41: #else
        !            42: #define DPRINTF(a)
        !            43: #endif
        !            44:
        !            45: paddr_t load_base;     /* current load address */
        !            46: paddr_t load_start;    /* start address for loading */
        !            47: int nr_img;            /* number of module images */
        !            48:
        !            49: struct boot_info *boot_info;    /* pointer to boot information. */
        !            50:
        !            51: /*
        !            52:  * Define memory block as reserved area.
        !            53:  */
        !            54: void
        !            55: reserve_memory(paddr_t start, size_t size)
        !            56: {
        !            57:        int i;
        !            58:        paddr_t mem_end;
        !            59:
        !            60:        DPRINTF(("reserved memory: start=%x size=%x\n", start, size));
        !            61:
        !            62:        if (boot_info->main_mem.size == 0)
        !            63:                panic("bad mem size");
        !            64:
        !            65:        mem_end = boot_info->main_mem.start + boot_info->main_mem.size;
        !            66:        if (start > mem_end)
        !            67:                return;
        !            68:        if (start + size > mem_end)
        !            69:                size = (size_t)(mem_end - start);
        !            70:
        !            71:        for (i = 0; i < NRESMEM; i++) {
        !            72:                if (boot_info->reserved[i].size == 0) {
        !            73:                        boot_info->reserved[i].start = start;
        !            74:                        boot_info->reserved[i].size = size;
        !            75:                        break;
        !            76:                }
        !            77:        }
        !            78:        if (i == NRESMEM)
        !            79:                panic("No memory slot to reserve");
        !            80: }
        !            81:
        !            82: /*
        !            83:  * Load all images.
        !            84:  * Return 0 on success, -1 on failure.
        !            85:  */
        !            86: static int
        !            87: load_image(struct ar_hdr *hdr, struct module *m)
        !            88: {
        !            89:        char *c;
        !            90:
        !            91:        if (strncmp((char *)&hdr->ar_fmag, ARFMAG, 2))
        !            92:                return -1;
        !            93:
        !            94:        strncpy((char *)&m->name, (char *)&hdr->ar_name, 16);
        !            95:        c = (char *)&m->name;
        !            96:        while (*c != '/' && *c != ' ')
        !            97:                c++;
        !            98:        *c = '\0';
        !            99:
        !           100:        DPRINTF(("loading: hdr=%x module=%x name=%s\n",
        !           101:                 (int)hdr, (int)m, (char *)&m->name));
        !           102:
        !           103:        if (elf_load((char *)hdr + sizeof(struct ar_hdr), m))
        !           104:                panic("Load error");
        !           105:        return 0;
        !           106: }
        !           107:
        !           108: #ifdef CONFIG_RAMDISK
        !           109: /*
        !           110:  * Setup for RAMDISK
        !           111:  */
        !           112: static void
        !           113: setup_ramdisk(struct ar_hdr *hdr)
        !           114: {
        !           115:        struct mem_map *ram_disk;
        !           116:        size_t size;
        !           117:
        !           118:        if (strncmp((char *)&hdr->ar_fmag, ARFMAG, 2))
        !           119:                return;
        !           120:        size = (size_t)atol((char *)&hdr->ar_size);
        !           121:        if (size == 0)
        !           122:                return;
        !           123:
        !           124:        ram_disk = (struct mem_map *)&boot_info->ram_disk;
        !           125:        ram_disk->start = (paddr_t)hdr + sizeof(struct ar_hdr);
        !           126:        ram_disk->size = size;
        !           127:
        !           128:        reserve_memory(ram_disk->start, ram_disk->size);
        !           129:
        !           130:        DPRINTF(("RAM disk base=%x size=%x\n", ram_disk->start,
        !           131:                 ram_disk->size));
        !           132: }
        !           133: #endif /* CONFIG_RAMDISK */
        !           134:
        !           135: /*
        !           136:  * Setup OS images - kernel, driver and boot tasks.
        !           137:  *
        !           138:  * It reads each module file image and copy it to the appropriate
        !           139:  * memory area. The image is built as generic archive (.a) file.
        !           140:  *
        !           141:  * The image information is stored into the boot information area.
        !           142:  */
        !           143: static void
        !           144: setup_image(void)
        !           145: {
        !           146:        char *hdr;
        !           147:        struct module *m;
        !           148:        char *magic;
        !           149:        int i;
        !           150:        long len;
        !           151:
        !           152:        /*
        !           153:         *  Validate archive image
        !           154:         */
        !           155:        magic = (char *)boot_info->archive;
        !           156:        if (strncmp(magic, ARMAG, 8))
        !           157:                panic("Invalid OS image");
        !           158:
        !           159:        /*
        !           160:         * Load kernel image
        !           161:         */
        !           162:        hdr = (char *)((paddr_t)magic + 8);
        !           163:        if (load_image((struct ar_hdr *)hdr, &boot_info->kernel))
        !           164:                panic("Can not load kernel");
        !           165:
        !           166:        /*
        !           167:         * Load driver module
        !           168:         */
        !           169:        len = atol((char *)&((struct ar_hdr *)hdr)->ar_size);
        !           170:        if (len == 0)
        !           171:                panic("Invalid OS image");
        !           172:        hdr = (char *)((paddr_t)hdr + sizeof(struct ar_hdr) + len);
        !           173:        if (load_image((struct ar_hdr *)hdr, &boot_info->driver))
        !           174:                panic("Can not load driver");
        !           175:
        !           176:        /*
        !           177:         * Load boot tasks
        !           178:         */
        !           179:        i = 0;
        !           180:        m = (struct module *)&boot_info->tasks[0];
        !           181:        while (1) {
        !           182:                /* Proceed to next archive header */
        !           183:                len = atol((char *)&((struct ar_hdr *)hdr)->ar_size);
        !           184:                if (len == 0)
        !           185:                        break;
        !           186:                hdr = (char *)((paddr_t)hdr + sizeof(struct ar_hdr) + len);
        !           187:
        !           188:                /* Pad to even boundary */
        !           189:                hdr += ((paddr_t)hdr % 2);
        !           190:
        !           191:                /* Check archive header */
        !           192:                if (strncmp((char *)&((struct ar_hdr *)hdr)->ar_fmag,
        !           193:                            ARFMAG, 2))
        !           194:                        break;
        !           195:
        !           196: #ifdef CONFIG_RAMDISK
        !           197:                /* Load RAM disk image */
        !           198:                if (!strncmp((char *)&((struct ar_hdr *)hdr)->ar_name,
        !           199:                            "ramdisk.a", 9)) {
        !           200:                        setup_ramdisk((struct ar_hdr *)hdr);
        !           201:                        continue;
        !           202:                }
        !           203: #endif /* CONFIG_RAMDISK */
        !           204:                /* Load task */
        !           205:                if (load_image((struct ar_hdr *)hdr, m))
        !           206:                        break;
        !           207:                i++;
        !           208:                m++;
        !           209:        }
        !           210:
        !           211:        boot_info->nr_tasks = i;
        !           212:
        !           213:        if (boot_info->nr_tasks == 0)
        !           214:                panic("No boot task found!");
        !           215:
        !           216:        /*
        !           217:         * Save information for boot modules.
        !           218:         * This includes kernel, driver, and boot tasks.
        !           219:         */
        !           220:        boot_info->modules.start = load_start;
        !           221:        boot_info->modules.size = (size_t)(load_base - load_start);
        !           222: }
        !           223:
        !           224: #ifdef DEBUG_BOOTINFO
        !           225: static void
        !           226: dump_image(struct module *m)
        !           227: {
        !           228:        printf("%s: entry=%x phys=%x size=%x text=%x data=%x textsz=%x datasz=%x bss=%x\n",
        !           229:               m->name, (int)m->entry, (int)m->phys, (int)m->size,
        !           230:               (int)m->text, (int)m->data, (int)m->textsz,
        !           231:               (int)m->datasz, (int)m->bsssz);
        !           232: }
        !           233:
        !           234: static void
        !           235: dump_bootinfo(void)
        !           236: {
        !           237:        struct module *m;
        !           238:        int i;
        !           239:
        !           240:        printf("main memory start=%x size=%x\n",
        !           241:               (int)boot_info->main_mem.start,
        !           242:               (int)boot_info->main_mem.size);
        !           243:
        !           244:        for (i = 0; i < NRESMEM; i++) {
        !           245:                if (boot_info->reserved[i].size != 0) {
        !           246:                        printf("reserved mem start=%x size=%x\n",
        !           247:                               (int)boot_info->reserved[i].start,
        !           248:                               (int)boot_info->reserved[i].size);
        !           249:                }
        !           250:        }
        !           251:        printf("ramdisk     start=%x size=%x\n",
        !           252:               (int)boot_info->ram_disk.start,
        !           253:               (int)boot_info->ram_disk.size);
        !           254:
        !           255:        dump_image(&boot_info->kernel);
        !           256:        dump_image(&boot_info->driver);
        !           257:
        !           258:        m = (struct module *)&boot_info->tasks[0];
        !           259:        for (i = 0; i < boot_info->nr_tasks; i++, m++)
        !           260:                dump_image(m);
        !           261: }
        !           262: #endif
        !           263:
        !           264: /*
        !           265:  * C entry point
        !           266:  */
        !           267: void
        !           268: loader_main(void)
        !           269: {
        !           270:        paddr_t kernel_entry;
        !           271:
        !           272:        DPRINTF(("Prex Boot Loader V1.00\n"));
        !           273:
        !           274:        load_base = 0;
        !           275:        load_start = 0;
        !           276:        nr_img = 0;
        !           277:
        !           278:        /*
        !           279:         * Get machine-dependent information.
        !           280:         */
        !           281:        setup_bootinfo(&boot_info);
        !           282:
        !           283:        /*
        !           284:         * Load program image.
        !           285:         */
        !           286:        setup_image();
        !           287:
        !           288: #ifdef DEBUG_BOOTINFO
        !           289:        dump_bootinfo();
        !           290: #endif
        !           291:
        !           292:        /*
        !           293:         * Jump to the kernel entry point
        !           294:         * via machine-dependent code.
        !           295:         */
        !           296:        kernel_entry = (paddr_t)phys_to_virt(boot_info->kernel.entry);
        !           297:        DPRINTF(("kernel_entry=%x\n", kernel_entry));
        !           298:        DPRINTF(("Entering kernel...\n\n"));
        !           299:        start_kernel(kernel_entry, (paddr_t)boot_info);
        !           300:
        !           301:        /* NOTREACHED */
        !           302: }

CVSweb