feat/kernel: Added First-Fit algorithm for kernel heap
This commit is contained in:
parent
65fbb97d8a
commit
6374144f4a
6 changed files with 134 additions and 2 deletions
|
@ -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)))
|
||||
|
|
|
@ -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
11
kernel/src/mm/heap.h
Normal 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
82
kernel/src/mm/heap/ff.c
Normal 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
18
kernel/src/mm/heap/ff.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue