1
0
Fork 0

feat/kernel: Added First-Fit algorithm for kernel heap

This commit is contained in:
Kevin Alavik 2025-05-15 19:52:40 +02:00
parent 65fbb97d8a
commit 6374144f4a
Signed by: cmpsb
GPG key ID: 10D1CC0526FDC6D7
6 changed files with 134 additions and 2 deletions

View file

@ -4,12 +4,14 @@
#include <boot/limine.h>
#include <stdint.h>
#include <mm/vmm.h>
extern uint64_t hhdm_offset;
extern struct limine_memmap_response *memmap;
extern uint64_t kvirt;
extern uint64_t kphys;
extern uint64_t kstack_top;
extern vctx_t *kvm_ctx;
#define HIGHER_HALF(ptr) ((void *)((uint64_t)(ptr) < hhdm_offset ? (uint64_t)(ptr) + hhdm_offset : (uint64_t)(ptr)))
#define PHYSICAL(ptr) ((void *)((uint64_t)(ptr) >= hhdm_offset ? (uint64_t)(ptr) - hhdm_offset : (uint64_t)(ptr)))

View file

@ -12,6 +12,7 @@
#include <mm/pmm.h>
#include <arch/paging.h>
#include <mm/vmm.h>
#include <mm/heap.h>
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
@ -31,6 +32,7 @@ struct limine_memmap_response *memmap = NULL;
uint64_t kvirt = 0;
uint64_t kphys = 0;
uint64_t kstack_top = 0;
vctx_t *kvm_ctx = NULL;
void emk_entry(void)
{
@ -91,7 +93,7 @@ void emk_entry(void)
log_early("Initialized paging");
/* Kernel Virtual Memory Context, not to be confused with KVM */
vctx_t *kvm_ctx = vinit(kernel_pagemap, 0x1000);
kvm_ctx = vinit(kernel_pagemap, 0x1000);
if (!kvm_ctx)
{
kpanic(NULL, "Failed to create kernel VMM context");
@ -108,5 +110,18 @@ void emk_entry(void)
vfree(kvm_ctx, b);
log_early("Initialized virtual page manager");
/* Setup kernel heap */
heap_init();
char *c = kmalloc(1);
if (!c)
{
kpanic(NULL, "Failed to allocate single byte on heap");
}
*c = 32;
log_early("Allocated 1 byte @ %llx", (uint64_t)c);
kfree(c);
log_early("Initialized kernel heap");
hlt();
}

11
kernel/src/mm/heap.h Normal file
View file

@ -0,0 +1,11 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#ifndef HEAP_H
#define HEAP_H
#include <stddef.h>
void heap_init();
void *kmalloc(size_t size);
void kfree(void *ptr);
#endif // HEAP_H

82
kernel/src/mm/heap/ff.c Normal file
View file

@ -0,0 +1,82 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#include <mm/heap/ff.h>
#include <mm/heap.h>
#include <mm/vmm.h>
#include <mm/pmm.h>
#include <boot/emk.h>
#include <util/align.h>
#include <sys/kpanic.h>
void *pool;
block_t *freelist = NULL;
void heap_init()
{
pool = valloc(kvm_ctx, FF_POOL_SIZE, VALLOC_RW);
if (!pool)
kpanic(NULL, "Failed to alloc memory for the heap pool");
freelist = (block_t *)pool;
freelist->size = (FF_POOL_SIZE * PAGE_SIZE) - sizeof(block_t);
freelist->next = NULL;
}
void *kmalloc(size_t size)
{
if (size == 0)
return NULL;
size = ALIGN_UP(size, 8);
block_t *prev = NULL;
block_t *cur = freelist;
while (cur)
{
if (cur->size >= size)
{
size_t tot_size = sizeof(block_t) + size;
if (cur->size >= ALIGN_UP(tot_size + sizeof(block_t), 8))
{
/* do splitting */
block_t *new_block = (block_t *)((uint8_t *)cur + tot_size);
new_block->size = cur->size - tot_size;
new_block->next = cur->next;
cur->size = size;
if (prev)
prev->next = new_block;
else
freelist = new_block;
}
else
{
/* use entire block */
if (prev)
prev->next = cur->next;
else
freelist = cur->next;
}
return (void *)((uint8_t *)cur + sizeof(block_t));
}
prev = cur;
cur = cur->next;
}
return NULL;
}
void kfree(void *ptr)
{
if (!ptr)
return;
/* get block header */
block_t *block = (block_t *)((uint8_t *)ptr - sizeof(block_t));
/* insert freed block at head of freelist */
block->next = freelist;
freelist = block;
}

18
kernel/src/mm/heap/ff.h Normal file
View file

@ -0,0 +1,18 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#ifndef FF_H
#define FF_H
/* Kevin's simple First-Fit allocator */
#include <stdint.h>
#include <stddef.h>
#define FF_POOL_SIZE 512 // 2MB, in pages
typedef struct block
{
size_t size;
struct block *next;
} block_t;
#endif // FF_H