Annotation of prex-old/boot/common/main.c, Revision 1.2
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: u_long load_base; /* current load address */
40: u_long load_start; /* start address for loading */
41: int nr_img; /* number of module images */
42:
43: struct boot_info *boot_info; /* pointer to boot information. */
44:
45: /*
46: * Define memory block as reserved area.
47: */
48: void
49: reserve_memory(u_long start, size_t size)
50: {
51: int i;
52: u_long mem_end;
53:
54: printk("reserve_memory: start=%x size=%x\n", start, size);
55:
56: if (boot_info->main_mem.size == 0)
57: panic("bad mem size");
58:
59: mem_end = boot_info->main_mem.start + boot_info->main_mem.size;
60: if (start > mem_end)
61: return;
62: if (start + size > mem_end)
63: size = mem_end - start;
64:
65: for (i = 0; i < NRESMEM; i++) {
66: if (boot_info->reserved[i].size == 0) {
67: boot_info->reserved[i].start = start;
68: boot_info->reserved[i].size = size;
69: break;
70: }
71: }
72: if (i == NRESMEM)
73: panic("No memory slot to reserve");
74: }
75:
76: /*
77: * Load all images.
78: * Return 0 on success, -1 on failure.
79: */
80: static int
81: load_image(struct ar_hdr *hdr, struct module *m)
82: {
83: char *c;
84:
85: if (strncmp((char *)&hdr->ar_fmag, ARFMAG, 2))
86: return -1;
87:
88: strncpy((char *)&m->name, (char *)&hdr->ar_name, 16);
89: c = (char *)&m->name;
90: while (*c != '/' && *c != ' ')
91: c++;
92: *c = '\0';
93: printk("load_image hdr=%x module=%x name=%s\n",
94: (int)hdr, (int)m, (char *)&m->name);
95: if (elf_load((char *)hdr + sizeof(struct ar_hdr), m))
96: panic("Load error");
97: return 0;
98: }
99:
100: #ifdef CONFIG_RAMDISK
101: /*
102: * Setup for RAMDISK
103: */
104: static void
105: setup_ramdisk(struct ar_hdr *hdr)
106: {
107: struct mem_map *ram_disk;
108: size_t size;
109:
110: if (strncmp((char *)&hdr->ar_fmag, ARFMAG, 2))
111: return;
112: size = (size_t)atol((char *)&hdr->ar_size);
113: if (size == 0)
114: return;
115:
116: ram_disk = (struct mem_map *)&boot_info->ram_disk;
117: ram_disk->start = (u_long)hdr + sizeof(struct ar_hdr);
118: ram_disk->size = size;
119:
120: reserve_memory(ram_disk->start, ram_disk->size);
121:
122: printk("RAM disk base=%x size=%x\n", ram_disk->start, ram_disk->size);
123: }
124: #endif /* CONFIG_RAMDISK */
125:
126: /*
127: * Setup OS images - kernel, driver and boot tasks.
128: *
129: * It reads each module file image and copy it to the appropriate
130: * memory area. The image is built as generic archive (.a) file.
131: *
132: * The image information is strored into the boot information area.
133: */
134: static void
135: setup_image(void)
136: {
137: char *hdr;
138: struct module *m;
139: char *magic;
140: int i;
141: long len;
142:
143: /*
144: * Validate archive image
145: */
146: magic = (char *)boot_info->archive;
147: if (strncmp(magic, ARMAG, 8))
148: panic("Invalid OS image");
149:
150: /*
151: * Load kernel image
152: */
153: hdr = (char *)((u_long)magic + 8);
154: if (load_image((struct ar_hdr *)hdr, &boot_info->kernel))
155: panic("Can not load kernel");
156:
157: /*
158: * Load driver module
159: */
160: len = atol((char *)&((struct ar_hdr *)hdr)->ar_size);
161: if (len == 0)
162: panic("Invalid OS image");
163: hdr = (char *)((u_long)hdr + sizeof(struct ar_hdr) + len);
164: if (load_image((struct ar_hdr *)hdr, &boot_info->driver))
165: panic("Can not load driver");
166:
167: /*
168: * Load boot tasks
169: */
170: i = 0;
171: m = (struct module *)&boot_info->tasks[0];
172: while (1) {
173: /* Proceed to next archive header */
174: len = atol((char *)&((struct ar_hdr *)hdr)->ar_size);
175: if (len == 0)
176: break;
177: hdr = (char *)((u_long)hdr + sizeof(struct ar_hdr) + len);
178:
179: /* Pad to even boundary */
180: hdr += ((u_long)hdr % 2);
181:
182: /* Check archive header */
183: if (strncmp((char *)&((struct ar_hdr *)hdr)->ar_fmag,
184: ARFMAG, 2))
185: break;
186:
187: #ifdef CONFIG_RAMDISK
188: /* Load RAM disk image */
189: if (!strncmp((char *)&((struct ar_hdr *)hdr)->ar_name,
190: "ramdisk.a", 9)) {
191: setup_ramdisk((struct ar_hdr *)hdr);
192: continue;
193: }
194: #endif /* CONFIG_RAMDISK */
195: /* Load task */
196: if (load_image((struct ar_hdr *)hdr, m))
197: break;
198: i++;
199: m++;
200: }
201:
202: boot_info->nr_tasks = i;
203:
1.2 ! nbrk 204: #if 0
1.1 nbrk 205: if (boot_info->nr_tasks == 0)
206: panic("No boot task found!");
1.2 ! nbrk 207: #endif
1.1 nbrk 208: /*
209: * Save information for boot modules.
210: * This includes kernel, driver, and boot tasks.
211: */
212: boot_info->modules.start = load_start;
213: boot_info->modules.size = (size_t)(load_base - load_start);
214: }
215:
216: #ifdef DEBUG_BOOT
217: static void
218: dump_image(struct module *m)
219: {
220: printk
221: ("%s: entry=%x phys=%x size=%x text=%x data=%x textsz=%x datasz=%x bss=%x\n",
222: m->name, (int)m->entry, (int)m->phys, (int)m->size,
223: (int)m->text, (int)m->data, (int)m->textsz,
224: (int)m->datasz, (int)m->bsssz);
225: }
226:
227: static void
228: dump_bootinfo(void)
229: {
230: struct module *m;
231: int i;
232:
233: printk("main memory start=%x size=%x\n",
234: (int)boot_info->main_mem.start,
235: (int)boot_info->main_mem.size);
236:
237: for (i = 0; i < NRESMEM; i++) {
238: if (boot_info->reserved[i].size != 0) {
239: printk("reserved mem start=%x size=%x\n",
240: (int)boot_info->reserved[i].start,
241: (int)boot_info->reserved[i].size);
242: }
243: }
244: printk("ramdisk start=%x size=%x\n",
245: (int)boot_info->ram_disk.start,
246: (int)boot_info->ram_disk.size);
247:
248: dump_image(&boot_info->kernel);
249: dump_image(&boot_info->driver);
250:
251: m = (struct module *)&boot_info->tasks[0];
252: for (i = 0; i < boot_info->nr_tasks; i++, m++)
253: dump_image(m);
254: }
255: #endif
256:
257: /*
258: * C entry point
259: */
260: void
261: loader_main(void)
262: {
263: u_int kernel_entry;
264:
265: printk("Prex Boot Loader V1.00\n");
266:
267: load_base = 0;
268: load_start = 0;
269: nr_img = 0;
270:
271: setup_bootinfo(&boot_info);
272: setup_image();
273: #ifdef DEBUG_BOOT
274: dump_bootinfo();
275: #endif
276: kernel_entry = (unsigned int)phys_to_virt(boot_info->kernel.entry);
277: printk("kernel_entry=%x\n", kernel_entry);
278: printk("Entering kernel...\n\n");
279: start_kernel(kernel_entry, (unsigned int)boot_info);
280: }
CVSweb