diff --git a/kernel/kmain.c b/kernel/kmain.c index abd743f..d95be46 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -136,7 +136,7 @@ void kmain(uint32_t magic, multiboot_info* mbi) { init_page_tables(); kprintf("Page tables initialized\n"); - kheap_init(); + kgrow(1); kprintf("Allocated 4kb for kernel heap\n"); kprintf("scanning for drives\n"); diff --git a/kernel/lib/memory.c b/kernel/lib/memory.c index d6c7fc2..244c098 100644 --- a/kernel/lib/memory.c +++ b/kernel/lib/memory.c @@ -1,6 +1,12 @@ #include "lib/memory.h" #include "memory/mm.h" +#define KHEAP_START 0xE0000000 + +typedef struct __attribute__((packed)) { + uint8_t free; + uint32_t next_blk; +} alloc_header_t; void memcpy(const void* src, void* dst, size_t sz) { for (size_t i = 0; i < sz; i++) { @@ -31,16 +37,58 @@ int strlen(const char* str) { return len; } -static void* kernel_heap = (void*)0xE0000000; -static size_t kernel_heap_sz = 0; +static void* kernel_heap_start = (void*)KHEAP_START; +static void* kernel_heap_end = (void*)KHEAP_START; +alloc_header_t* blk_list = NULL; -void kheap_init() { - if (kernel_heap_sz == 0) { +void kgrow(size_t pages) { + if (kernel_heap_end == kernel_heap_start) { + // probaably not great, but if we don't have a heap yet, allocate the first (or only) frame requested. + // Then initialize the first block header for the allocator void* frame = p_alloc_frame(); - map_page((uint32_t)kernel_heap, (uint32_t)frame, PAGE_PRESENT | PAGE_WRITABLE); + map_page((uint32_t)kernel_heap_end, (uint32_t)frame, PAGE_PRESENT | PAGE_WRITABLE); + kernel_heap_end = (void*)((uint32_t)kernel_heap_end + PAGE_SIZE); + pages--; + blk_list = kernel_heap_start; + blk_list->free = 1; + blk_list->next_blk = 0; + } + + for (size_t p = 0; p < pages; p++) { + void* frame = p_alloc_frame(); + map_page((uint32_t)kernel_heap_end, (uint32_t)frame, PAGE_PRESENT | PAGE_WRITABLE); + kernel_heap_end = (void*)((uint32_t)kernel_heap_end + PAGE_SIZE); } } -void* alloc(size_t sz) { +void* kalloc(size_t sz) { + if (sz == 0) { + return NULL; + } + alloc_header_t* header = blk_list; + while (!header->free) { + if (header->next_blk == 0) { + return NULL; + } + header = (alloc_header_t*)header->next_blk; + } + + uint32_t data_ptr = (uint32_t)header + sizeof(alloc_header_t); + if (data_ptr >= (uint32_t)kernel_heap_end) { + return NULL; + } // if the start of the data is already at the end, we don't have room + + uint32_t end_of_blk = data_ptr + sz; + if (end_of_blk > (uint32_t)kernel_heap_end) { + return NULL; + } // if the end of the data is past the end, we don't have room + + if (end_of_blk != header->next_blk && end_of_blk < ((uint32_t)kernel_heap_end - sizeof(alloc_header_t))) { + header->next_blk = end_of_blk; + alloc_header_t* next_header = (alloc_header_t*)header->next_blk; + next_header->f + } // see if we have room to place the next header and at least 1 byte of data + + return (void*)data_ptr; } \ No newline at end of file diff --git a/kernel/lib/memory.h b/kernel/lib/memory.h index fc24efa..562b757 100644 --- a/kernel/lib/memory.h +++ b/kernel/lib/memory.h @@ -10,7 +10,7 @@ void memset(const uint8_t* dst, uint8_t val, size_t sz); int strcmp(const char *s1, const char *s2); int strlen(const char* str); -void kheap_init(); +void kgrow(size_t pages); void* alloc(size_t sz);