diff options
author | neal <neal> | 2008-08-14 13:12:31 +0000 |
---|---|---|
committer | neal <neal> | 2008-08-14 13:12:31 +0000 |
commit | 2f4992bc5b1f1e996c1a6b8139754459d4f76434 (patch) | |
tree | 9fced7ffbd52650a37043df53ad4deec72272011 /laden | |
parent | 868ccb816257ccea6fdb6d99772c8a561d938e22 (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/ChangeLog | 16 | ||||
-rw-r--r-- | laden/ia32-cmain.c | 92 | ||||
-rw-r--r-- | laden/kip-fixup.c | 20 | ||||
-rw-r--r-- | laden/laden.c | 16 | ||||
-rw-r--r-- | laden/laden.h | 8 | ||||
-rw-r--r-- | laden/loader.c | 156 |
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 |