summaryrefslogtreecommitdiff
path: root/laden
diff options
context:
space:
mode:
authorneal <neal>2008-08-14 13:12:31 +0000
committerneal <neal>2008-08-14 13:12:31 +0000
commit2f4992bc5b1f1e996c1a6b8139754459d4f76434 (patch)
tree9fced7ffbd52650a37043df53ad4deec72272011 /laden
parent868ccb816257ccea6fdb6d99772c8a561d938e22 (diff)
2008-08-14 Neal H. Walfield <neal@gnu.org>
* laden.h: Include <stdint.h>. (total_memory): New declaration. * laden.c (total_memory): New definition. (load_components): Remove V2 specific code. * kip-fixup.c (kip_fixup): Remove V2 specific code. * ia32-cmain.c (find_components): Add module regions as type -1, not L4_MEMDESC_BOOTLOADER. Don't make total_memory a local variable. Also calculate the total memory in the case where only MBI->MEM_LOWER and MBI->MEM_UPPER are available. Move kernel memory reservation from here... * loader.c (loader_regions_reserve): ... to here. Implement more robustly. Always add descriptors for all memory regions with a type other than -1.
Diffstat (limited to 'laden')
-rw-r--r--laden/ChangeLog16
-rw-r--r--laden/ia32-cmain.c92
-rw-r--r--laden/kip-fixup.c20
-rw-r--r--laden/laden.c16
-rw-r--r--laden/laden.h8
-rw-r--r--laden/loader.c156
6 files changed, 172 insertions, 136 deletions
diff --git a/laden/ChangeLog b/laden/ChangeLog
index 5a6555e..2df72c0 100644
--- a/laden/ChangeLog
+++ b/laden/ChangeLog
@@ -1,3 +1,19 @@
+2008-08-14 Neal H. Walfield <neal@gnu.org>
+
+ * laden.h: Include <stdint.h>.
+ (total_memory): New declaration.
+ * laden.c (total_memory): New definition.
+ (load_components): Remove V2 specific code.
+ * kip-fixup.c (kip_fixup): Remove V2 specific code.
+ * ia32-cmain.c (find_components): Add module regions as type -1,
+ not L4_MEMDESC_BOOTLOADER. Don't make total_memory a local
+ variable. Also calculate the total memory in the case where only
+ MBI->MEM_LOWER and MBI->MEM_UPPER are available. Move kernel
+ memory reservation from here...
+ * loader.c (loader_regions_reserve): ... to here. Implement more
+ robustly. Always add descriptors for
+ all memory regions with a type other than -1.
+
2008-06-29 Neal H. Walfield <neal@gnu.org>
* ia32-cmain.c (debug_dump): Don't include redundant \n's in
diff --git a/laden/ia32-cmain.c b/laden/ia32-cmain.c
index c2288c8..e936f59 100644
--- a/laden/ia32-cmain.c
+++ b/laden/ia32-cmain.c
@@ -309,8 +309,7 @@ find_components (void)
loader_add_region ("modules", start, end,
modules_relocate,
(void *) (l4_word_t) ((start_module << 16)
- | count),
- L4_MEMDESC_BOOTLOADER);
+ | count), -1);
start = mod[i].mod_start;
start_module = i;
count = 1;
@@ -322,8 +321,7 @@ find_components (void)
loader_add_region ("modules", start, end,
modules_relocate,
(void *) (l4_word_t) ((start_module << 16)
- | count),
- L4_MEMDESC_BOOTLOADER);
+ | count), -1);
}
/* Now create the memory map. */
@@ -332,8 +330,6 @@ find_components (void)
memory by default to allow arbitrary device access. */
add_memory_map (0, -1, L4_MEMDESC_SHARED, 0);
- uint64_t total_memory = 0;
-
/* Now add what GRUB tells us. */
if (CHECK_FLAG (mbi->flags, 6))
{
@@ -377,90 +373,24 @@ find_components (void)
L4_MEMDESC_CONVENTIONAL, 0);
add_memory_map (0x100000, (0x100000 + (mbi->mem_upper << 10)) - 1,
L4_MEMDESC_CONVENTIONAL, 0);
+
+ total_memory = (mbi->mem_lower << 10) + (mbi->mem_upper << 10);
}
+ debug (1, "total memory reported by GRUB: %lld KB",
+ total_memory / 1024);
+
/* 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);
-#ifdef _L4_X2
-#define KMEM_MIN_CHUNK 0x400000
-
- /* Reserve 20% of the conventional memory for the kernel. */
- uint64_t kmem_needed = ((total_memory / 5) + KMEM_MIN_CHUNK)
- & ~(KMEM_MIN_CHUNK - 1);
-
- /* The upper limit for the end of the kernel memory. */
-#define KMEM_MAX (240 * 0x100000 - 1)
-
- if (CHECK_FLAG (mbi->flags, 6))
- {
- memory_map_t *mmap;
-
- for (mmap = (memory_map_t *) mbi->mmap_addr;
- (uint32_t) mmap < mbi->mmap_addr + mbi->mmap_length;
- mmap = (memory_map_t *) ((uint32_t) mmap
- + mmap->size + sizeof (mmap->size)))
- {
- if (mmap->type != 1)
- continue;
-
- if (((uint32_t) mmap->length) >= KMEM_MIN_CHUNK
- && ((uint32_t) mmap->base_addr) <= KMEM_MAX - KMEM_MIN_CHUNK)
- {
- uint32_t low = (uint32_t) mmap->base_addr;
- uint32_t high = low + (uint32_t) mmap->length - 1;
-
- if (high > KMEM_MAX)
- high = KMEM_MAX;
-
- /* Round up. */
- low = (low + KMEM_MIN_CHUNK - 1) & ~(KMEM_MIN_CHUNK - 1);
- /* Round down (high is last valid byte!). */
- high = ((high + 1) & ~(KMEM_MIN_CHUNK - 1)) - 1;
-
- if (high - low + 1 > kmem_needed)
- low = high + 1 - kmem_needed;
- if (high - low + 1 < KMEM_MIN_CHUNK)
- continue;
-
- add_memory_map (low, high, L4_MEMDESC_RESERVED, 0);
-
- kmem_needed -= high - low + 1;
- }
- }
-
- if (kmem_needed)
- panic ("Failed to reserve %d kb memory for the kernel!",
- kmem_needed);
- }
- else if (CHECK_FLAG (mbi->flags, 0))
- {
- if ((mbi->mem_upper << 10) >= kmem_needed)
- {
- uint32_t high = (mbi->mem_upper << 10) + 0x100000;
- uint32_t low;
-
- if (high > KMEM_MAX)
- high = KMEM_MAX;
-
- low = high - kmem_needed;
- /* Round up to the next super page (4 MB). */
- low = (low + KMEM_MIN_CHUNK - 1) & ~(KMEM_MIN_CHUNK - 1);
-
- add_memory_map (low, high, L4_MEMDESC_RESERVED, 0);
- }
- }
-#endif
-
/* Now protect ourselves and the mulitboot info. */
loader_add_region (program_name, (l4_word_t) &_start, (l4_word_t) &_end,
NULL, NULL, -1);
start = (l4_word_t) mbi;
end = start + sizeof (*mbi);
- loader_add_region ("grub-mbi", start, end, mbi_relocate, NULL,
- L4_MEMDESC_BOOTLOADER);
+ loader_add_region ("grub-mbi", start, end, mbi_relocate, NULL, -1);
if (CHECK_FLAG (mbi->flags, 3) && mbi->mods_count)
{
@@ -469,8 +399,7 @@ find_components (void)
start = (l4_word_t) mod;
end = ((l4_word_t) mod) + mbi->mods_count * sizeof (*mod);
loader_add_region ("grub-mods-metadata", start, end,
- mods_relocate, NULL,
- L4_MEMDESC_BOOTLOADER);
+ mods_relocate, NULL, -1);
l4_word_t nr;
for (nr = 0; nr < mbi->mods_count; nr++)
@@ -478,8 +407,7 @@ find_components (void)
loader_add_region ("grub-mods-cmdlines",
mod[nr].string,
mod[nr].string + strlen ((char *) mod[nr].string),
- cmdline_relocate, (void *) nr,
- L4_MEMDESC_BOOTLOADER);
+ cmdline_relocate, (void *) nr, -1);
}
/* Protect the first page. */
diff --git a/laden/kip-fixup.c b/laden/kip-fixup.c
index f26d3d4..079837a 100644
--- a/laden/kip-fixup.c
+++ b/laden/kip-fixup.c
@@ -1,5 +1,5 @@
/* kip-fixup.c - Fixup the L4 KIP.
- Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
Written by Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -49,20 +49,10 @@ kip_fixup (void)
l4_api_version_t api_version = l4_api_version_from (kip);
switch (api_version.version)
{
-#ifdef _L4_V2
- case L4_API_VERSION_2:
- case L4_API_VERSION_2PP:
- /* Booting a v2 kernel. */
- debug (1, "Booting a v2 kernel.");
- break;
-#endif
-
-#ifdef _L4_X2
case L4_API_VERSION_X2:
/* Booting an x2 kernel. */
debug (1, "Booting an x2 kernel.");
break;
-#endif
default:
panic ("Don't know how to boot kernel with API version %x.%x\n",
@@ -94,13 +84,11 @@ kip_fixup (void)
(char *) memory_map,
sizeof (l4_memory_desc_t) * memory_map_size);
-#ifdef _L4_X2
kip->memory_info.nr = memory_map_size;
-#endif
-
for (nr = 0; nr < memory_map_size; nr++)
- debug (1, "Memory Map %i: Type %i/%i, Low 0x%llx, High 0x%llx",
- nr + 1, memory_map[nr].type, memory_map[nr].subtype,
+ debug (1, "Memory Map %i: Type %s(%i)/%i, Low 0x%llx, High 0x%llx",
+ nr + 1, l4_memory_desc_type_to_string (memory_map[nr].type),
+ memory_map[nr].type, memory_map[nr].subtype,
(unsigned long long) (memory_map[nr].low << 10),
(unsigned long long) (memory_map[nr].high << 10));
diff --git a/laden/laden.c b/laden/laden.c
index 70d1ba8..99d01d4 100644
--- a/laden/laden.c
+++ b/laden/laden.c
@@ -1,5 +1,5 @@
/* laden.c - Main function for laden.
- Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
Written by Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -36,6 +36,8 @@ l4_rootserver_t rootserver;
/* The boot info to be inserted into the L4 KIP. */
l4_word_t boot_info;
+/* Total memory (in bytes). */
+uint64_t total_memory;
static void
rootserver_relocate (const char *name,
@@ -55,7 +57,7 @@ static void
load_components (void)
{
/* Make sure that the required components are available and mark the
- memory their packed images occupy as used. */
+ memory their packed images as used. */
if (!kernel.low)
panic ("No L4 kernel found");
loader_add_region ("kernel-mod", kernel.low, kernel.high,
@@ -84,11 +86,6 @@ load_components (void)
loader_elf_load ("sigma0", sigma0.low, sigma0.high,
&sigma0.low, &sigma0.high, &sigma0.ip, -1);
loader_remove_region ("sigma0-mod");
-#ifdef _L4_V2
- /* Use the page following the extracted image as the stack. */
- /* XXX: Should reserve this? */
- sigma0.sp = ((sigma0.high + 0xfff) & ~0xfff) + 0x1000;
-#endif
if (sigma1.low)
{
@@ -100,11 +97,6 @@ load_components (void)
loader_elf_load ("rootserver", rootserver.low, rootserver.high,
&rootserver.low, &rootserver.high, &rootserver.ip, -1);
loader_remove_region ("rootserver-mod");
-#ifdef _L4_V2
- /* Use the page following the extracted image as the stack. */
- /* XXX: Should reserve this? */
- rootserver.sp = ((rootserver.high + 0xfff) & ~0xfff) + 0x1000;
-#endif
}
diff --git a/laden/laden.h b/laden/laden.h
index bf8bb18..567845d 100644
--- a/laden/laden.h
+++ b/laden/laden.h
@@ -1,5 +1,5 @@
/* laden.h - Generic definitions.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2008 Free Software Foundation, Inc.
Written by Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -23,6 +23,7 @@
#endif
#include <string.h>
+#include <stdint.h>
#include <assert.h>
#include <l4.h>
@@ -58,6 +59,11 @@ extern l4_rootserver_t rootserver;
must provide this information. */
extern l4_word_t boot_info;
+/* Total memory in bytes. To be filled in by the architecture
+ specific code (find_components). */
+extern uint64_t total_memory;
+
+
/* The memory map to be provided to the kernel. */
#define MEMORY_MAP_MAX 200
extern l4_memory_desc_t memory_map[MEMORY_MAP_MAX];
diff --git a/laden/loader.c b/laden/loader.c
index 0651c07..582b130 100644
--- a/laden/loader.c
+++ b/laden/loader.c
@@ -1,5 +1,5 @@
/* loader.c - Load ELF files.
- Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
Written by Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -65,9 +65,6 @@ mem_check (const char *name, l4_word_t start, l4_word_t end)
if (!loader_get_num_memory_desc ())
return;
- /* FIXME: This implementation does not account for conventional
- memory overriding non-conventional memory in the descriptor
- list. */
for (nr = 0; nr < loader_get_num_memory_desc (); nr++)
{
memdesc = loader_get_memory_desc (nr);
@@ -80,8 +77,8 @@ mem_check (const char *name, l4_word_t start, l4_word_t end)
&& end >= l4_memory_desc_low (memdesc)
&& end <= l4_memory_desc_high (memdesc))
{
- debug (1, "Memory 0x%x-0x%x fits in conventional memory map %d "
- "(0x%x-0x%x)",
+ debug (1, "Memory 0x%x-0x%x fits in conventional memory "
+ "(map %d: 0x%x-0x%x)",
start, end, nr,
l4_memory_desc_low (memdesc),
l4_memory_desc_high (memdesc));
@@ -99,11 +96,12 @@ mem_check (const char *name, l4_word_t start, l4_word_t end)
|| (start < l4_memory_desc_low (memdesc)
&& end > l4_memory_desc_high (memdesc)))
{
- debug (1, "Memory 0x%x-0x%x conflicts with non-conventional "
- "memory map %d (0x%x-0x%x)",
- start, end, nr,
- l4_memory_desc_low (memdesc),
- l4_memory_desc_high (memdesc));
+ if (fits)
+ debug (1, "Memory 0x%x-0x%x conflicts with non-conventional "
+ "memory map %d: 0x%x-0x%x",
+ start, end, nr,
+ l4_memory_desc_low (memdesc),
+ l4_memory_desc_high (memdesc));
fits = 0;
conflicts = 1 + nr;
}
@@ -116,8 +114,9 @@ mem_check (const char *name, l4_word_t start, l4_word_t end)
{
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%"
+ "with memory of type %s(%i)/%i (0x%" L4_PRIxWORD " - 0x%"
L4_PRIxWORD ")", name, start, end + 1,
+ l4_memory_desc_type_to_string (memdesc->type),
memdesc->type, memdesc->subtype,
l4_memory_desc_low (memdesc), l4_memory_desc_high (memdesc));
}
@@ -158,7 +157,7 @@ loader_add_region (const char *name, l4_word_t start, l4_word_t end,
relocate_region rr, void *cookie,
int desc_type)
{
- debug (1, "Protected Region: %s (0x%x - 0x%x)", name, start, end);
+ debug (1, "Reserving region for %s: 0x%x - 0x%x", name, start, end);
if (start >= end)
panic ("Region %s has a start address following the end address", name);
@@ -176,7 +175,7 @@ loader_add_region (const char *name, l4_word_t start, l4_word_t end,
break;
if (region == MAX_REGIONS)
- panic ("Out of memory region descriptors, region %s doesn't fit",
+ panic ("Out of memory region descriptors, can't add region %s",
name);
}
else
@@ -198,7 +197,7 @@ loader_add_region (const char *name, l4_word_t start, l4_word_t end,
&& ((start >= used_regions[i].start && start < used_regions[i].end)
|| (end >= used_regions[i].start && end <= used_regions[i].end)
|| (start < used_regions[i].start && end > used_regions[i].start)))
- /* Region REGION conflict with region I. Try to relocate region
+ /* Region conflicts with region I. Try to relocate region
I. */
{
l4_word_t mstart = used_regions[i].start;
@@ -319,22 +318,129 @@ loader_remove_region (const char *name)
void
loader_regions_reserve (void)
{
-#ifdef _L4_V2
+ debug (1, "Reserving memory");
+
int i;
for (i = 0; i < nr_regions; i++)
- if (used_regions[i].used && used_regions[i].desc_type != -1)
+ {
+ /* Round down. */
+ used_regions[i].start &= ~0x3ff;
+ /* Round up. */
+ used_regions[i].end = ((used_regions[i].end + 0x3ff - 1) & ~0x3ff) - 1;
+
+ debug (1, "%s: %x-%x", used_regions[i].name,
+ used_regions[i].start, used_regions[i].end);
+
+ if (used_regions[i].used && used_regions[i].desc_type != -1)
+ {
+ debug (1, "Reserving memory 0x%x-0x%x (%s)",
+ used_regions[i].start, used_regions[i].end,
+ used_regions[i].name);
+
+ add_memory_map (used_regions[i].start, used_regions[i].end,
+ used_regions[i].desc_type, 0);
+ }
+ }
+
+
+ /* Reserve memory for the kernel. */
+#define KMEM_MIN_CHUNK 0x400000
+#define KMEM_MAX (240 * 0x100000 - 1)
+
+ /* Reserve 20% of the conventional memory for the kernel. */
+ uint32_t kmem_needed = ((total_memory / 5) + KMEM_MIN_CHUNK)
+ & ~(KMEM_MIN_CHUNK - 1);
+
+ debug (1, "Reserving %d KB for the kernel", kmem_needed / 1024);
+
+ uint32_t start = 0;
+ uint32_t reserved = 0;
+ while (reserved < kmem_needed && start < KMEM_MAX)
+ {
+ int fits = 0;
+ uint32_t end = KMEM_MAX;
+
+#define RUP(x) (((x) + KMEM_MIN_CHUNK - 1) & ~(KMEM_MIN_CHUNK - 1))
+#define RDOWN(x) ((x) & ~(KMEM_MIN_CHUNK - 1))
+
+ bool check (uint32_t rstart, uint32_t rend, int reserved)
{
- /* Round down. */
- l4_word_t start = used_regions[i].start & ~0x3ff;
- /* Round up. */
- l4_word_t end = ((used_regions[i].end + 0x3ff - 1) & ~0x3ff) - 1;
+ if (! reserved)
+ {
+ if (start >= rstart && start <= rend)
+ {
+ if (end > rend)
+ /* Round down to a multiple of KMEM_MIN_CHUNK. */
+ end = RDOWN (rend + 1) - 1;
+
+ if (end - start + 1 >= KMEM_MIN_CHUNK)
+ fits = 1;
+ else
+ return false;
+ }
+ }
+ else if (fits)
+ {
+ if (start >= rstart && start <= rend)
+ /* Start falls within the region. Move past it. */
+ start = RUP (rend + 1);
+
+ if (start < rstart && end > rstart)
+ /* Start comes before the region. Bound END by
+ it. */
+ end = RDOWN (rstart - 1);
- debug (1, "Reserving memory 0x%x-0x%x (%s)",
- start, end, used_regions[i].name);
+ if (! (end > start && end - start + 1 > KMEM_MIN_CHUNK))
+ {
+ fits = 0;
+ return false;
+ }
+ }
- add_memory_map (start, end, used_regions[i].desc_type, 0);
+ return true;
}
-#endif
+
+ int nr;
+ for (nr = 0; nr < loader_get_num_memory_desc (); nr++)
+ {
+ l4_memory_desc_t *memdesc = loader_get_memory_desc (nr);
+
+ if (! check (l4_memory_desc_low (memdesc),
+ l4_memory_desc_high (memdesc),
+ memdesc->type != L4_MEMDESC_CONVENTIONAL))
+ break;
+ }
+
+ if (nr == loader_get_num_memory_desc ())
+ {
+ int i;
+ for (i = 0; i < nr_regions; i++)
+ if (! check (used_regions[i].start,
+ used_regions[i].end, 1))
+ break;
+ }
+
+ if (fits)
+ /* Reserve the memory. */
+ {
+ if (end - start + 1 > kmem_needed - reserved)
+ /* Reserve at most KMEM_NEEDED - RESERVED bytes. */
+ end = start + (kmem_needed - reserved) - 1;
+
+ debug (1, "Reserving memory 0x%x-0x%x (%d KB) for kernel",
+ start, end + 1, (end - start + 1) / 1024);
+
+ add_memory_map (start, end, L4_MEMDESC_RESERVED, 0);
+
+ reserved += end - start + 1;
+ }
+
+ start += KMEM_MIN_CHUNK;
+ }
+
+ if (reserved < kmem_needed)
+ debug (1, "Reserved %d kb for the kernel but wanted to reserve %d kb",
+ reserved / 1024, kmem_needed / 1024);
}
/* Get the memory range to which the ELF image from START to END