summaryrefslogtreecommitdiff
path: root/laden
diff options
context:
space:
mode:
authormarcus <marcus>2003-10-04 17:42:21 +0000
committermarcus <marcus>2003-10-04 17:42:21 +0000
commitceaac94423467dec53971816ad8caed7c38319ce (patch)
tree0804273b97cab5b7ed260e321ef159d19067d3fc /laden
parent481d7a188c7788f8bab0638cbe36bd3445020440 (diff)
laden/
2003-10-04 Marcus Brinkmann <marcus@gnu.org> * laden.h (add_memory_map): Don't round END up to 1K. * ia32-cmain.c (find_components): Pass the address of the last byte as END to add_memory_map. Don't do bogus alignment check without BIOS map. Add 0xc0000 - 0xf0000 as shared memory. Initially, add the whole address space as shared memory to allow arbitrary device access. * loader.c: Include <l4/kip.h>. (mem_check): Change type of address args to l4_word_t. Use l4_memory_desc_low and l4_memory_desc_high to determine range of memory descriptor. The high address is inclusive now, so take this into account. Allow conventional memory descriptors to override non-conventional. Use L4_PRIxWORD. wortel/ 2003-10-04 Marcus Brinkmann <marcus@gnu.org> * loader.c: Include <l4/kip.h>. (mem_check): Change type of address args to l4_word_t. Use l4_memory_desc_low and l4_memory_desc_high to determine range of memory descriptor. The high address is inclusive now, so take this into account. Allow conventional memory descriptors to override non-conventional. Use L4_PRIxWORD.
Diffstat (limited to 'laden')
-rw-r--r--laden/ChangeLog15
-rw-r--r--laden/ia32-cmain.c46
-rw-r--r--laden/laden.h6
-rw-r--r--laden/loader.c116
4 files changed, 135 insertions, 48 deletions
diff --git a/laden/ChangeLog b/laden/ChangeLog
index 7658cb7..59d22b2 100644
--- a/laden/ChangeLog
+++ b/laden/ChangeLog
@@ -1,3 +1,18 @@
+2003-10-04 Marcus Brinkmann <marcus@gnu.org>
+
+ * laden.h (add_memory_map): Don't round END up to 1K.
+ * ia32-cmain.c (find_components): Pass the address of the last
+ byte as END to add_memory_map. Don't do bogus alignment check
+ without BIOS map. Add 0xc0000 - 0xf0000 as shared memory.
+ Initially, add the whole address space as shared memory to allow
+ arbitrary device access.
+ * loader.c: Include <l4/kip.h>.
+ (mem_check): Change type of address args to l4_word_t. Use
+ l4_memory_desc_low and l4_memory_desc_high to determine range of
+ memory descriptor. The high address is inclusive now, so take
+ this into account. Allow conventional memory descriptors to
+ override non-conventional. Use L4_PRIxWORD.
+
2003-09-29 Marcus Brinkmann <marcus@gnu.org>
* loader.c (loader_elf_load): Fix wordsize check. Submitted by
diff --git a/laden/ia32-cmain.c b/laden/ia32-cmain.c
index 591943c..7c38ceb 100644
--- a/laden/ia32-cmain.c
+++ b/laden/ia32-cmain.c
@@ -36,6 +36,7 @@ help_arch (void)
"through to the rootserver\n"
"and handled by it.\n";
}
+
/* Start kernel by simply jumping to the entry point. */
void
@@ -215,6 +216,12 @@ find_components (void)
}
/* Now create the memory map. */
+
+ /* First, add the whole address space as shared memory by default to
+ allow arbitrary device access. */
+ add_memory_map (0, -1, L4_MEMDESC_SHARED, 0);
+
+ /* Now add what GRUB tells us. */
if (CHECK_FLAG (mbi->flags, 6))
{
/* mmap_* are valid. */
@@ -230,26 +237,9 @@ find_components (void)
if (mmap->base_addr >> 32)
panic ("L4 does not support more than 4 GB on ia32");
- end = mmap->base_addr + mmap->length;
+ end = mmap->base_addr + mmap->length - 1;
- if (end == (1ULL << 32))
- {
-#if 0
- panic ("L4 does not support exactly 4 GB on ia32");
-#elif 1
- /* The L4 specification does not seem to allow this
- configuration. Truncate the region by dropping the
- last page. FIXME: kickstart overflows and sets the
- high address to 0. This is unambiguous, but needs to
- be supported by sigma0 and the operating system.
- Clarification of the specification is required. */
- end = (1ULL << 32) - (1 << 10);
-#else
- /* This is effectively what kickstart does. */
- end = 0;
-#endif
- }
- else if (end >> 32)
+ if (end >> 32)
panic ("L4 does not support more than 4 GB on ia32");
if (mmap->base_addr & ((1 << 10) - 1)
@@ -266,20 +256,16 @@ find_components (void)
else if (CHECK_FLAG (mbi->flags, 0))
{
/* mem_* are valid. */
- if (mbi->mem_lower & 0x2ff)
- panic ("Lower memory end address 0x%x is unaligned",
- mbi->mem_lower);
- if (mbi->mem_upper & 0x2ff)
- panic ("Upper memory end address 0x%x is unaligned",
- mbi->mem_upper);
-
- add_memory_map (0, mbi->mem_lower << 10, L4_MEMDESC_CONVENTIONAL, 0);
- add_memory_map (0x100000, 0x100000 + (mbi->mem_upper << 10),
+
+ add_memory_map (0, (mbi->mem_lower << 10) - 1,
+ L4_MEMDESC_CONVENTIONAL, 0);
+ add_memory_map (0x100000, (0x100000 + (mbi->mem_upper << 10)) - 1,
L4_MEMDESC_CONVENTIONAL, 0);
}
- /* The VGA memory is usually not included in the BIOS map. */
- add_memory_map (0xa0000, 0xc0000, L4_MEMDESC_SHARED, 0);
+ /* The VGA memory, and ROM extension, is usually not included in the
+ BIOS map. We add it here. */
+ add_memory_map (0xa0000, 0xf0000 - 1, L4_MEMDESC_SHARED, 0);
/* The amount of conventional memory to be reserved for the kernel. */
#define KMEM_SIZE (16 * 0x100000)
diff --git a/laden/laden.h b/laden/laden.h
index 276e775..56aa84a 100644
--- a/laden/laden.h
+++ b/laden/laden.h
@@ -48,7 +48,7 @@ typedef __l4_rootserver_t rootserver_t;
/* For the rootserver components, find_components() must fill in the
start and end address of the ELF images in memory. The end address
- is one more than the last byte in the image. */
+ is one more than the address of the last byte in the image. */
extern rootserver_t kernel;
extern rootserver_t sigma0;
extern rootserver_t sigma1;
@@ -63,12 +63,12 @@ extern l4_word_t boot_info;
extern struct l4_memory_desc memory_map[MEMORY_MAP_MAX];
extern l4_word_t memory_map_size;
-#define add_memory_map(start,end,mtype,msubtype) \
+#define add_memory_map(start, end, mtype, msubtype) \
({ \
if (memory_map_size == MEMORY_MAP_MAX) \
panic ("No more memory descriptor slots available.\n"); \
memory_map[memory_map_size].low = (start) >> 10; \
- memory_map[memory_map_size].high = ((end) + (1 << 10) - 1) >> 10; \
+ memory_map[memory_map_size].high = (end) >> 10; \
memory_map[memory_map_size].virtual = 0; \
memory_map[memory_map_size].type = (mtype); \
memory_map[memory_map_size].subtype = (msubtype); \
diff --git a/laden/loader.c b/laden/loader.c
index a7a6575..249c6a4 100644
--- a/laden/loader.c
+++ b/laden/loader.c
@@ -23,6 +23,7 @@
#endif
#include <string.h>
+#include <l4/kip.h>
#include "loader.h"
#include "output.h"
@@ -34,7 +35,7 @@
/* Verify that the memory region START to END (exclusive) is valid. */
static void
-mem_check (const char *name, unsigned long start, unsigned long end)
+mem_check (const char *name, l4_word_t start, l4_word_t end)
{
l4_memory_desc_t memdesc;
int nr;
@@ -44,6 +45,8 @@ mem_check (const char *name, unsigned long start, unsigned long end)
if (!loader_get_num_memory_desc ())
return;
+ end--;
+
/* FIXME: This implementation does not account for conventional
memory overriding non-conventional memory in the descriptor
list. */
@@ -54,31 +57,44 @@ mem_check (const char *name, unsigned long start, unsigned long end)
if (memdesc->type == L4_MEMDESC_CONVENTIONAL)
{
/* Check if the region fits into conventional memory. */
- if (start >= (memdesc->low << 10) && start < (memdesc->high << 10)
- && end > (memdesc->low << 10) && end <= (memdesc->high << 10))
+ if (start >= l4_memory_desc_low (memdesc)
+ && start <= l4_memory_desc_high (memdesc)
+ && end >= l4_memory_desc_low (memdesc)
+ && end <= l4_memory_desc_high (memdesc))
fits = 1;
}
else
{
/* Check if the region overlaps with non-conventional
memory. */
- if ((start >= (memdesc->low << 10) && start < (memdesc->high << 10))
- || (end > (memdesc->low << 10) && end <= (memdesc->high << 10))
- || (start < (memdesc->low << 10) && end > (memdesc->high << 10)))
+ if ((start >= l4_memory_desc_low (memdesc)
+ && start <= l4_memory_desc_high (memdesc))
+ || (end >= l4_memory_desc_low (memdesc)
+ && end <= l4_memory_desc_high (memdesc))
+ || (start < l4_memory_desc_low (memdesc)
+ && end > l4_memory_desc_high (memdesc)))
{
- conflicts = 1;
- break;
+ fits = 0;
+ conflicts = 1 + nr;
}
}
}
- if (conflicts)
- panic ("%s (0x%x - 0x%x) conflicts with memory of "
- "type %i/%i (0x%x - 0x%x)", name, start, end,
- memdesc->type, memdesc->subtype,
- memdesc->low << 10, memdesc->high << 10);
+
if (!fits)
- panic ("%s (0x%x - 0x%x) does not fit into memory",
- name, start, end);
+ {
+ if (conflicts)
+ {
+ memdesc = loader_get_memory_desc (conflicts - 1);
+ panic ("%s (0x%" L4_PRIxWORD " - 0x%" L4_PRIxWORD ") conflicts "
+ "with memory of type %i/%i (0x%" L4_PRIxWORD " - 0x%"
+ L4_PRIxWORD ")", name, start, end + 1,
+ memdesc->type, memdesc->subtype,
+ l4_memory_desc_low (memdesc), l4_memory_desc_high (memdesc));
+ }
+ else
+ panic ("%s (0x%" L4_PRIxWORD " - 0x%" L4_PRIxWORD ") does not fit "
+ "into memory", name, start, end + 1);
+ }
}
@@ -128,6 +144,9 @@ loader_add_region (const char *name, l4_word_t start, l4_word_t end)
if (nr_regions == MAX_REGIONS)
panic ("Too many memory regions, region %s doesn't fit", name);
+ if (start >= end)
+ panic ("Region %s has a start address following the end address", name);
+
check_region (name, start, end);
used_regions[nr_regions].name = name;
@@ -159,6 +178,73 @@ loader_remove_region (const char *name)
}
+/* Get the memory range to which the ELF image from START to END
+ (exclusive) will be loaded. NAME is used for panic messages. */
+void
+loader_elf_dest (const char *name, l4_word_t start, l4_word_t end,
+ l4_word_t *new_start_p, l4_word_t *new_end_p)
+{
+ l4_word_t new_start = -1;
+ l4_word_t new_end = 0;
+ int i;
+
+ Elf32_Ehdr *elf = (Elf32_Ehdr *) start;
+
+ if (elf->e_ident[EI_MAG0] != ELFMAG0
+ || elf->e_ident[EI_MAG1] != ELFMAG1
+ || elf->e_ident[EI_MAG2] != ELFMAG2
+ || elf->e_ident[EI_MAG3] != ELFMAG3)
+ panic ("%s is not an ELF file", name);
+
+ if (elf->e_type != ET_EXEC)
+ panic ("%s is not an executable file", name);
+
+ if (!elf->e_phoff)
+ panic ("%s has no valid program header offset", name);
+
+ /* FIXME: Some architectures support both word sizes. */
+ if (!((elf->e_ident[EI_CLASS] == ELFCLASS32
+ && L4_WORDSIZE == L4_WORDSIZE_32)
+ || (elf->e_ident[EI_CLASS] == ELFCLASS64
+ && L4_WORDSIZE == L4_WORDSIZE_64)))
+ panic ("%s has invalid word size", name);
+ if (!((elf->e_ident[EI_DATA] == ELFDATA2LSB
+ && L4_BYTE_ORDER == L4_LITTLE_ENDIAN)
+ || (elf->e_ident[EI_DATA] == ELFDATA2MSB
+ && L4_BYTE_ORDER == L4_BIG_ENDIAN)))
+ panic ("%s has invalid byte order", name);
+
+#if i386
+# define elf_machine EM_386
+#elif PPC
+# define elf_machine EM_PPC
+#else
+# error Not ported to this architecture!
+#endif
+
+ if (elf->e_machine != elf_machine)
+ panic ("%s is not for this architecture", name);
+
+ for (i = 0; i < elf->e_phnum; i++)
+ {
+ Elf32_Phdr *ph = (Elf32_Phdr *) (start + elf->e_phoff
+ + i * elf->e_phentsize);
+ if (ph->p_type == PT_LOAD)
+ {
+ if (ph->p_paddr < new_start)
+ new_start = ph->p_paddr;
+ if (ph->p_memsz + ph->p_paddr > new_end)
+ new_end = ph->p_memsz + ph->p_paddr;
+ }
+ }
+
+ if (new_start_p)
+ *new_start_p = new_start;
+ if (new_end_p)
+ *new_end_p = new_end;
+}
+
+
/* Load the ELF image from START to END (exclusive) into memory under
the name NAME (also used as the name for the region of the
resulting ELF program). Return the lowest and highest address used