diff options
Diffstat (limited to 'src/kernel/mem/mem.c')
-rw-r--r-- | src/kernel/mem/mem.c | 93 |
1 files changed, 59 insertions, 34 deletions
diff --git a/src/kernel/mem/mem.c b/src/kernel/mem/mem.c index 8d814e4..3310b70 100644 --- a/src/kernel/mem/mem.c +++ b/src/kernel/mem/mem.c @@ -5,11 +5,7 @@ #include <config.h> -#ifdef K_USE_BASIC_HEAP -#include "heap.basic.h" -#else -#include "heap.std.h" -#endif +#include "_dlmalloc.h" #include "mem.h" @@ -20,7 +16,7 @@ #define KHEAP_MAXSIZE 0x08000000 size_t mem_placementAddr; -static uint32_t kheap_working = 0; +int _no_more_ksbrk = 0; // ****************************** @@ -38,12 +34,13 @@ static void get_free_pages() { if (locked) return; locked = 1; while (freepagecount < FREEPAGESTOKEEP) { - if (kheap_working) { + if (_no_more_ksbrk) { for (i = 0xFFFFF000; i >= 0xF0000000; i -= 0x1000) { if (pagedir_getPage(kernel_pagedir, i, 1)->frame == 0) break; } freepages[freepagecount].virt = i; - freepages[freepagecount].phys = frame_alloc() * 0x1000; + uint32_t frame = frame_alloc(); + freepages[freepagecount].phys = frame * 0x1000; page_map(pagedir_getPage(kernel_pagedir, i, 0), freepages[freepagecount].phys / 0x1000, 0, 0); freepagecount++; } else { @@ -51,7 +48,7 @@ static void get_free_pages() { mem_placementAddr &= 0xFFFFF000; mem_placementAddr += 0x1000; } - freepages[freepagecount].virt = (size_t)kmalloc(0x1000); + freepages[freepagecount].virt = (size_t)ksbrk(0x1000); freepages[freepagecount].phys = freepages[freepagecount].virt - K_HIGHHALF_ADDR; freepagecount++; } @@ -72,41 +69,69 @@ void* kmalloc_page(size_t *phys) { void kfree_page(void* ptr) { size_t addr = (size_t)ptr; - if (kheap_working) { //With this we can know if paging works + if (_no_more_ksbrk) { page_unmapFree(pagedir_getPage(kernel_pagedir, addr, 0)); } } //*********************************** -// NORMAL MEMORY ALLOCATION +// MEMORY ALLOCATION FOR DLMALLOC // ************************* -static struct heap kheap; - -/* Called on kernel start. Creates the kernel heap. */ -void kheap_init() { -#ifdef K_USE_BASIC_HEAP - heap_create(&kheap, (mem_placementAddr & 0xFFFFF000) + 0x1000, KHEAP_INITSIZE, KHEAP_MAXSIZE); -#else - heap_create(&kheap, (mem_placementAddr & 0xFFFFF000) + 0x1000, KHEAP_IDXSIZE, KHEAP_INITSIZE, KHEAP_MAXSIZE); -#endif - kheap_working = 1; - monitor_write("[KHeap] "); -} +void* ksbrk(size_t size) { + if (_no_more_ksbrk == 0) { // ksbrk is NOT being called by dlmalloc + if (size & 0x0FFF) { + size = (size & 0xFFFFF000) + 0x1000; + } + } -/* Allocates on the heap if possible. If not possible, allocates just after the kernel code. */ -void* kmalloc(size_t size) { - if (kheap_working) { - return heap_alloc(&kheap, size); - } else { - size_t tmp = mem_placementAddr; - mem_placementAddr += size; - return (void*)tmp; + size_t tmp = mem_placementAddr; + size_t er_begin, er_end, i; + + /* (DBG) monitor_write("<ksbrk "); + monitor_writeHex(size); + monitor_write(":"); + monitor_writeHex(tmp); + monitor_write("> "); */ + + mem_placementAddr += size; + + if (_no_more_ksbrk) { // paging enabled, we must allocate these pages + if (tmp < mem_placementAddr) { + er_begin = tmp; + if (er_begin & 0x0FFF) er_begin = (er_begin & 0xFFFFF000) + 0x1000; + er_end = mem_placementAddr; + if (er_end & 0x0FFF) er_end = (er_end & 0xFFFFF000) + 0x1000; + for (i = er_begin; i < er_end; i += 0x1000) { + struct page *p = pagedir_getPage(kernel_pagedir, i, 1); + size_t f = frame_alloc(); + page_map(p, f, 0, 0); + /* (DBG) monitor_write("<map "); monitor_writeHex(i); monitor_write(" "); + monitor_writeHex(f); monitor_write("> "); */ + } + } else if (tmp > mem_placementAddr) { + er_begin = (size_t)mem_placementAddr; + if (er_begin & 0x0FFF) er_begin = (er_begin & 0xFFFFF000) + 0x1000; + er_end = tmp; + if (er_end & 0x0FFF) er_end = (er_end & 0xFFFFF000) + 0x1000; + for (i = er_end - 0x1000; i >= er_begin; i -= 0x1000) { + // (DBG) monitor_write("<unmap:"); monitor_writeHex(i); monitor_write("> "); + page_unmapFree(pagedir_getPage(kernel_pagedir, i, 0)); + } + } } + + return (void*)tmp; } -void kfree(void* ptr) { - if (kheap_working) { - heap_free(&kheap, ptr); +void kbrk(void* ptr) { + monitor_write("<kbrk "); + monitor_writeHex(ptr); + monitor_write(">\n"); + + if ((size_t)ptr > (size_t)&end) { + ksbrk(ptr - (size_t)mem_placementAddr); + } else { + PANIC("INVALID KBRK."); } } |