Annotation of prex-old/boot/common/main.c, Revision 1.1.1.1.2.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:
1.1.1.1.2.1! nbrk 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 */
1.1 nbrk 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
1.1.1.1.2.1! nbrk 55: reserve_memory(paddr_t start, size_t size)
1.1 nbrk 56: {
57: int i;
1.1.1.1.2.1! nbrk 58: paddr_t mem_end;
1.1 nbrk 59:
1.1.1.1.2.1! nbrk 60: DPRINTF(("reserved memory: start=%x size=%x\n", start, size));
1.1 nbrk 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)
1.1.1.1.2.1! nbrk 69: size = (size_t)(mem_end - start);
1.1 nbrk 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';
1.1.1.1.2.1! nbrk 99:
! 100: DPRINTF(("loading: hdr=%x module=%x name=%s\n",
! 101: (int)hdr, (int)m, (char *)&m->name));
! 102:
1.1 nbrk 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;
1.1.1.1.2.1! nbrk 125: ram_disk->start = (paddr_t)hdr + sizeof(struct ar_hdr);
1.1 nbrk 126: ram_disk->size = size;
127:
128: reserve_memory(ram_disk->start, ram_disk->size);
129:
1.1.1.1.2.1! nbrk 130: DPRINTF(("RAM disk base=%x size=%x\n", ram_disk->start,
! 131: ram_disk->size));
1.1 nbrk 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: *
1.1.1.1.2.1! nbrk 141: * The image information is stored into the boot information area.
1.1 nbrk 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: */
1.1.1.1.2.1! nbrk 162: hdr = (char *)((paddr_t)magic + 8);
1.1 nbrk 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");
1.1.1.1.2.1! nbrk 172: hdr = (char *)((paddr_t)hdr + sizeof(struct ar_hdr) + len);
1.1 nbrk 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;
1.1.1.1.2.1! nbrk 186: hdr = (char *)((paddr_t)hdr + sizeof(struct ar_hdr) + len);
1.1 nbrk 187:
188: /* Pad to even boundary */
1.1.1.1.2.1! nbrk 189: hdr += ((paddr_t)hdr % 2);
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 224: #ifdef DEBUG_BOOTINFO
1.1 nbrk 225: static void
226: dump_image(struct module *m)
227: {
1.1.1.1.2.1! nbrk 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);
1.1 nbrk 232: }
233:
234: static void
235: dump_bootinfo(void)
236: {
237: struct module *m;
238: int i;
239:
1.1.1.1.2.1! nbrk 240: printf("main memory start=%x size=%x\n",
1.1 nbrk 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) {
1.1.1.1.2.1! nbrk 246: printf("reserved mem start=%x size=%x\n",
1.1 nbrk 247: (int)boot_info->reserved[i].start,
248: (int)boot_info->reserved[i].size);
249: }
250: }
1.1.1.1.2.1! nbrk 251: printf("ramdisk start=%x size=%x\n",
1.1 nbrk 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: {
1.1.1.1.2.1! nbrk 270: paddr_t kernel_entry;
1.1 nbrk 271:
1.1.1.1.2.1! nbrk 272: DPRINTF(("Prex Boot Loader V1.00\n"));
1.1 nbrk 273:
274: load_base = 0;
275: load_start = 0;
276: nr_img = 0;
277:
1.1.1.1.2.1! nbrk 278: /*
! 279: * Get machine-dependent information.
! 280: */
1.1 nbrk 281: setup_bootinfo(&boot_info);
1.1.1.1.2.1! nbrk 282:
! 283: /*
! 284: * Load program image.
! 285: */
1.1 nbrk 286: setup_image();
1.1.1.1.2.1! nbrk 287:
! 288: #ifdef DEBUG_BOOTINFO
1.1 nbrk 289: dump_bootinfo();
290: #endif
1.1.1.1.2.1! nbrk 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 */
1.1 nbrk 302: }
CVSweb