Annotation of prex-old/boot/common/main.c, Revision 1.1.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: 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:
204: if (boot_info->nr_tasks == 0)
205: panic("No boot task found!");
206:
207: /*
208: * Save information for boot modules.
209: * This includes kernel, driver, and boot tasks.
210: */
211: boot_info->modules.start = load_start;
212: boot_info->modules.size = (size_t)(load_base - load_start);
213: }
214:
215: #ifdef DEBUG_BOOT
216: static void
217: dump_image(struct module *m)
218: {
219: printk
220: ("%s: entry=%x phys=%x size=%x text=%x data=%x textsz=%x datasz=%x bss=%x\n",
221: m->name, (int)m->entry, (int)m->phys, (int)m->size,
222: (int)m->text, (int)m->data, (int)m->textsz,
223: (int)m->datasz, (int)m->bsssz);
224: }
225:
226: static void
227: dump_bootinfo(void)
228: {
229: struct module *m;
230: int i;
231:
232: printk("main memory start=%x size=%x\n",
233: (int)boot_info->main_mem.start,
234: (int)boot_info->main_mem.size);
235:
236: for (i = 0; i < NRESMEM; i++) {
237: if (boot_info->reserved[i].size != 0) {
238: printk("reserved mem start=%x size=%x\n",
239: (int)boot_info->reserved[i].start,
240: (int)boot_info->reserved[i].size);
241: }
242: }
243: printk("ramdisk start=%x size=%x\n",
244: (int)boot_info->ram_disk.start,
245: (int)boot_info->ram_disk.size);
246:
247: dump_image(&boot_info->kernel);
248: dump_image(&boot_info->driver);
249:
250: m = (struct module *)&boot_info->tasks[0];
251: for (i = 0; i < boot_info->nr_tasks; i++, m++)
252: dump_image(m);
253: }
254: #endif
255:
256: /*
257: * C entry point
258: */
259: void
260: loader_main(void)
261: {
262: u_int kernel_entry;
263:
264: printk("Prex Boot Loader V1.00\n");
265:
266: load_base = 0;
267: load_start = 0;
268: nr_img = 0;
269:
270: setup_bootinfo(&boot_info);
271: setup_image();
272: #ifdef DEBUG_BOOT
273: dump_bootinfo();
274: #endif
275: kernel_entry = (unsigned int)phys_to_virt(boot_info->kernel.entry);
276: printk("kernel_entry=%x\n", kernel_entry);
277: printk("Entering kernel...\n\n");
278: start_kernel(kernel_entry, (unsigned int)boot_info);
279: }
CVSweb