#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++) { ((uint8_t*)dst)[i] = ((uint8_t*)src)[i]; } } void memset(const uint8_t* dst, uint8_t val, size_t sz) { for (size_t i = 0; i < sz; i++) { ((uint8_t*)dst)[i] = val; } } int strcmp(const char* s1, const char* s2) { while (*s1 && (*s1 == *s2)) { s1++; s2++; } return *(const uint8_t*)s1 - *(const uint8_t*)s2; } int strlen(const char* str) { int len = 0; while(*str != 0) { str++; len++; } return len; } static void* kernel_heap_start = (void*)KHEAP_START; static void* kernel_heap_end = (void*)KHEAP_START; alloc_header_t* blk_list = NULL; 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_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* 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; }