From 1f164a7a4ef955d3dbc4fcb8d92485a49654e5ac Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Mon, 6 Aug 2018 18:41:45 +0200 Subject: [PATCH] First step for memory management --- core/main.c | 9 +++++++++ core/mem.c | 26 ++++++++++++++++++++++++++ core/mem.h | 18 ++++++++++++++++++ linker.ld | 3 +++ 4 files changed, 56 insertions(+) create mode 100644 core/mem.c create mode 100644 core/mem.h diff --git a/core/main.c b/core/main.c index f7eca30..46d40f9 100644 --- a/core/main.c +++ b/core/main.c @@ -4,6 +4,7 @@ #include "interrupt.h" #include "io.h" #include "irq.h" +#include "mem.h" #include "multiboot.h" #include "pit.h" #include "types.h" @@ -19,6 +20,7 @@ void cpuid(int code, uint32_t *a, uint32_t *d) // Multiboot information available here : https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec void kmain(unsigned long magic, unsigned long addr) { + unsigned long upper_mem = 0; initVGA(BLACK, GREEN); printString("Setting up IDT\n"); gdtSetup(); @@ -35,6 +37,7 @@ void kmain(unsigned long magic, unsigned long addr) printString("KB mem_upper = "); printInt((unsigned)mbi->mem_upper); printString("KB\n"); + upper_mem = mbi->mem_upper; } /* Is boot_device valid? */ @@ -52,6 +55,12 @@ void kmain(unsigned long magic, unsigned long addr) } } + if(upper_mem == 0){ + printString("Cannot get upper phy mem bound. Using default value 32MB\n"); + upper_mem = 32 * 1024; + } + memInit(upper_mem); + printString("Setting up IRQ handlers\n"); irqSetRoutine(IRQ_KEYBOARD, keyboard_handler); irqSetRoutine(IRQ_TIMER, timer_handler); diff --git a/core/mem.c b/core/mem.c new file mode 100644 index 0000000..9197715 --- /dev/null +++ b/core/mem.c @@ -0,0 +1,26 @@ +#include "mem.h" +#include "vga.h" + +struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end; + +int memInit(unsigned long upper_mem) +{ + printString("Free Mem going from "); + printInt((unsigned long)&__ld_kernel_end); + printString(" to "); + printInt(upper_mem * 1024); + printString("\n"); + unsigned long memdesc_end = + (unsigned long)page_desc + + ((upper_mem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc); + uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1; + for (uint i = 0; i < (upper_mem / (PAGE_SIZE / 1024)); i++) { + struct mem_desc *mem = &page_desc[i]; + if (i < lastUsed) + mem->ref = 1; + else + mem->ref = 0; + mem->phy_addr = i * PAGE_SIZE; + } + return 0; +} diff --git a/core/mem.h b/core/mem.h new file mode 100644 index 0000000..9cb8069 --- /dev/null +++ b/core/mem.h @@ -0,0 +1,18 @@ +#pragma once +#include "types.h" + + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1 << PAGE_SHIFT) + +// Defined in linker.ld script +extern uint32_t __ld_kernel_begin; +extern uint32_t __ld_kernel_end; + +struct mem_desc{ + unsigned long phy_addr; + unsigned long ref; +}; + + +int memInit(unsigned long upper_mem); diff --git a/linker.ld b/linker.ld index 88b0e01..c59a4ce 100644 --- a/linker.ld +++ b/linker.ld @@ -16,6 +16,7 @@ SECTIONS .text BLOCK(4K) : ALIGN(4K) { *(.multiboot) + __ld_kernel_begin = .; *(.text) } @@ -38,6 +39,8 @@ SECTIONS *(.bss) } + __ld_kernel_end = .; + /* The compiler may produce other sections, by default it will put them in a segment with the same name. Simply add stuff here as needed. */ }