Files
RockOS/kernel/lib/memory.c

94 lines
2.7 KiB
C
Raw Normal View History

#include "lib/memory.h"
#include "memory/mm.h"
2026-06-25 14:03:35 -05:00
#define KHEAP_START 0xE0000000
typedef struct __attribute__((packed)) {
uint8_t free;
uint32_t next_blk;
} alloc_header_t;
2026-06-24 13:30:23 -05:00
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;
}
}
2026-06-24 13:30:23 -05:00
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;
}
2026-06-25 14:03:35 -05:00
static void* kernel_heap_start = (void*)KHEAP_START;
static void* kernel_heap_end = (void*)KHEAP_START;
alloc_header_t* blk_list = NULL;
2026-06-25 14:03:35 -05:00
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();
2026-06-25 14:03:35 -05:00
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);
}
}
2026-06-25 14:03:35 -05:00
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
2026-06-25 14:03:35 -05:00
return (void*)data_ptr;
2026-06-24 13:30:23 -05:00
}