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