From 92c90c299acf8c328a6eef922daed49295d88186 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 30 Jun 2014 00:10:04 +0200 Subject: [PATCH] added bitmap initialization based on Multiboot infos --- arch/x86/include/asm/multiboot.h | 7 +++ kernel/main.c | 24 ++++++-- mm/memory.c | 95 ++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/multiboot.h b/arch/x86/include/asm/multiboot.h index 4756db5..a4d5c23 100644 --- a/arch/x86/include/asm/multiboot.h +++ b/arch/x86/include/asm/multiboot.h @@ -41,6 +41,13 @@ #include +/// Does the bootloader provide mem_* fields? +#define MULTIBOOT_INFO_MEM (1 << 0) +/// Does the bootloader provide a list of modules? +#define MULTIBOOT_INFO_MODS (1 << 3) +/// Does the bootloader provide a full memory map? +#define MULTIBOOT_INFO_MEM_MAP (1 << 6) + typedef uint16_t multiboot_uint16_t; typedef uint32_t multiboot_uint32_t; typedef uint64_t multiboot_uint64_t; diff --git a/kernel/main.c b/kernel/main.c index 34b8642..dd84a8c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -33,10 +33,14 @@ #include #include #include +#include + #include #include +#include +#include -/* +/* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. */ @@ -47,6 +51,11 @@ extern const void bss_end; extern char __BUILD_DATE; extern char __BUILD_TIME; +/* Page frame counters */ +atomic_int32_t total_pages; +atomic_int32_t total_allocated_pages; +atomic_int32_t total_available_pages; + static void userfoo(void* arg) { char str[256]; @@ -91,6 +100,7 @@ static int eduos_init(void) // initialize .bss section memset((void*)&bss_start, 0x00, ((size_t) &bss_end - (size_t) &bss_start)); + memory_init(); system_init(); irq_init(); timer_init(); @@ -104,16 +114,18 @@ int main(void) { tid_t id1; tid_t id2; + eduos_init(); - - kprintf("This is eduOS %s Build %u, %u\n", EDUOS_VERSION, &__BUILD_DATE, &__BUILD_TIME); - kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end); - irq_enable(); system_calibration(); + kprintf("This is eduOS %s Build %u, %u\n", EDUOS_VERSION, &__BUILD_DATE, &__BUILD_TIME); + kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end); kprintf("Processor frequency: %u MHz\n", get_cpu_frequency()); - + kprintf("Total memory: %lu KiB\n", atomic_int32_read(&total_pages) * PAGE_SIZE / 1024); + kprintf("Total memory available: %lu KiB\n", atomic_int32_read(&total_available_pages) * PAGE_SIZE / 1024); + + create_kernel_task(&id1, foo, "foo1", NORMAL_PRIO); create_kernel_task(&id2, wrapper, "userfoo", NORMAL_PRIO); diff --git a/mm/memory.c b/mm/memory.c index 6c40471..072ba63 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -27,12 +27,20 @@ #include #include +#include +#include #include #include #include #include +/* + * Note that linker symbols are not variables, they have no memory allocated for + * maintaining a value, rather their address is their value. + */ +extern const void kernel_start; +extern const void kernel_end; static char stack[MAX_TASKS-1][KERNEL_STACK_SIZE]; static char bitmap[BITMAP_SIZE]; @@ -142,3 +150,90 @@ int put_pages(size_t phyaddr, size_t npages) return ret; } + +int memory_init(void) +{ + unsigned int i; + size_t addr; + int ret = 0; + + // mark all memory as used + memset(bitmap, 0xff, BITMAP_SIZE); + + if (mb_info) { + if (mb_info->flags & MULTIBOOT_INFO_MEM_MAP) { + multiboot_memory_map_t* mmap = (multiboot_memory_map_t*) ((size_t) mb_info->mmap_addr); + multiboot_memory_map_t* mmap_end = (void*) ((size_t) mb_info->mmap_addr + mb_info->mmap_length); + + // mark available memory as free + while (mmap < mmap_end) { + if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) { + for (addr=mmap->addr; addr < mmap->addr + mmap->len; addr += PAGE_SIZE) { + page_clear_mark(addr >> PAGE_BITS); + atomic_int32_inc(&total_pages); + atomic_int32_inc(&total_available_pages); + } + } + mmap++; + } + } + else if (mb_info->flags & MULTIBOOT_INFO_MEM) { + size_t page; + size_t pages_lower = mb_info->mem_lower >> 2; + size_t pages_upper = mb_info->mem_upper >> 2; + + for (page=0; page> PAGE_BITS); + atomic_int32_inc(&total_allocated_pages); + atomic_int32_dec(&total_available_pages); + + + if (mb_info->flags & MULTIBOOT_INFO_MODS) { + // mark modules list as used + for(addr=mb_info->mods_addr; addrmods_addr+mb_info->mods_count*sizeof(multiboot_module_t); addr+=PAGE_SIZE) { + page_set_mark(addr >> PAGE_BITS); + atomic_int32_inc(&total_allocated_pages); + atomic_int32_dec(&total_available_pages); + } + + // mark modules as used + multiboot_module_t* mmodule = (multiboot_module_t*) ((size_t) mb_info->mods_addr); + for(i=0; imods_count; i++) { + for(addr=mmodule[i].mod_start; addr> PAGE_BITS); + atomic_int32_inc(&total_allocated_pages); + atomic_int32_dec(&total_available_pages); + } + } + } + } + + // mark kernel as used + for(addr=(size_t) &kernel_start; addr<(size_t) &kernel_end; addr+=PAGE_SIZE) { + page_set_mark(addr >> PAGE_BITS); + atomic_int32_inc(&total_allocated_pages); + atomic_int32_dec(&total_available_pages); + } + + // enable paging and map SMP, VGA, Multiboot modules etc. + /*ret = page_init(); + if (BUILTIN_EXPECT(ret, 0)) + return ret; + */ + + return ret; +}