18 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
19 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ |
20 |
|
|
21 |
#include "laden.h" |
#include "loader.h" |
22 |
|
#include "output.h" |
23 |
|
#include "shutdown.h" |
24 |
|
|
25 |
#include "elf.h" |
#include "elf.h" |
26 |
|
|
30 |
static void |
static void |
31 |
mem_check (const char *name, unsigned long start, unsigned long end) |
mem_check (const char *name, unsigned long start, unsigned long end) |
32 |
{ |
{ |
33 |
|
l4_memory_desc_t memdesc; |
34 |
int nr; |
int nr; |
35 |
int fits = 0; |
int fits = 0; |
36 |
int conflicts = 0; |
int conflicts = 0; |
37 |
|
|
38 |
|
if (!loader_get_num_memory_desc ()) |
39 |
|
return; |
40 |
|
|
41 |
/* FIXME: This implementation does not account for conventional |
/* FIXME: This implementation does not account for conventional |
42 |
memory overriding non-conventional memory in the descriptor |
memory overriding non-conventional memory in the descriptor |
43 |
list. */ |
list. */ |
44 |
|
for (nr = 0; nr < loader_get_num_memory_desc (); nr++) |
|
for (nr = 0; nr < memory_map_size; nr++) |
|
45 |
{ |
{ |
46 |
l4_memory_desc_t memdesc = &memory_map[nr]; |
memdesc = loader_get_memory_desc (nr); |
47 |
|
|
48 |
if (memdesc->type == L4_MEMDESC_CONVENTIONAL) |
if (memdesc->type == L4_MEMDESC_CONVENTIONAL) |
49 |
{ |
{ |
68 |
if (conflicts) |
if (conflicts) |
69 |
panic ("%s (0x%x - 0x%x) conflicts with memory of " |
panic ("%s (0x%x - 0x%x) conflicts with memory of " |
70 |
"type %i/%i (0x%x - 0x%x)", name, start, end, |
"type %i/%i (0x%x - 0x%x)", name, start, end, |
71 |
memory_map[nr].type, memory_map[nr].subtype, |
memdesc->type, memdesc->subtype, |
72 |
memory_map[nr].low << 10, memory_map[nr].high << 10); |
memdesc->low << 10, memdesc->high << 10); |
73 |
if (!fits) |
if (!fits) |
74 |
panic ("%s (0x%x - 0x%x) does not fit into memory", |
panic ("%s (0x%x - 0x%x) does not fit into memory", |
75 |
name, start, end); |
name, start, end); |
132 |
|
|
133 |
|
|
134 |
/* Remove the region with the name NAME from the table. */ |
/* Remove the region with the name NAME from the table. */ |
135 |
static void |
void |
136 |
remove_region (const char *name) |
loader_remove_region (const char *name) |
137 |
{ |
{ |
138 |
int i; |
int i; |
139 |
|
|
158 |
program). Return the lowest and highest address used by the |
program). Return the lowest and highest address used by the |
159 |
program in NEW_START_P and NEW_END_P, and the entry point in |
program in NEW_START_P and NEW_END_P, and the entry point in |
160 |
ENTRY. */ |
ENTRY. */ |
161 |
static void |
void |
162 |
elf_load (char *name, l4_word_t start, l4_word_t end, |
loader_elf_load (char *name, l4_word_t start, l4_word_t end, |
163 |
l4_word_t *new_start_p, l4_word_t *new_end_p, l4_word_t *entry) |
l4_word_t *new_start_p, l4_word_t *new_end_p, |
164 |
|
l4_word_t *entry) |
165 |
{ |
{ |
166 |
l4_word_t new_start = -1; |
l4_word_t new_start = -1; |
167 |
l4_word_t new_end = 0; |
l4_word_t new_end = 0; |
222 |
if (entry) |
if (entry) |
223 |
*entry = elf->e_entry; |
*entry = elf->e_entry; |
224 |
} |
} |
|
|
|
|
|
|
|
/* Load the ELF images of the kernel and the initial servers into |
|
|
memory, checking for overlaps. Update the start and end |
|
|
information with the information from the ELF program, and fill in |
|
|
the entry points. */ |
|
|
void |
|
|
load_components (void) |
|
|
{ |
|
|
if (!kernel.low) |
|
|
panic ("No L4 kernel found"); |
|
|
loader_add_region ("kernel-mod", kernel.low, kernel.high); |
|
|
|
|
|
if (!sigma0.low) |
|
|
panic ("No sigma0 server found"); |
|
|
loader_add_region ("sigma0-mod", sigma0.low, sigma0.high); |
|
|
|
|
|
if (sigma1.low) |
|
|
loader_add_region ("sigma1-mod", sigma1.low, sigma1.high); |
|
|
|
|
|
if (!rootserver.low) |
|
|
panic ("No rootserver server found"); |
|
|
loader_add_region ("rootserver-mod", rootserver.low, rootserver.high); |
|
|
|
|
|
elf_load ("kernel", kernel.low, kernel.high, |
|
|
&kernel.low, &kernel.high, &kernel.ip); |
|
|
remove_region ("kernel-mod"); |
|
|
|
|
|
elf_load ("sigma0", sigma0.low, sigma0.high, |
|
|
&sigma0.low, &sigma0.high, &sigma0.ip); |
|
|
remove_region ("sigma0-mod"); |
|
|
|
|
|
if (sigma1.low) |
|
|
{ |
|
|
elf_load ("sigma1", sigma1.low, sigma1.high, |
|
|
&sigma1.low, &sigma1.high, &sigma1.ip); |
|
|
remove_region ("sigma1-mod"); |
|
|
} |
|
|
|
|
|
elf_load ("rootserver", rootserver.low, rootserver.high, |
|
|
&rootserver.low, &rootserver.high, &rootserver.ip); |
|
|
remove_region ("rootserver-mod"); |
|
|
} |
|