summaryrefslogtreecommitdiff
path: root/src/kernel/mem/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/mem/mem.c')
-rw-r--r--src/kernel/mem/mem.c93
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.");
}
}