From e301006c1494674d94e1bcedcd3c3a638af7ec00 Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Sun, 26 Nov 2023 18:49:11 -0600 Subject: arch: i386: alloc: add a physical memory manager Add a simple, bitmap-based physical memory management system. Signed-off-by: Danny Holman --- arch/i386/include/kernel/alloc.h | 13 ++++++++++++ arch/i386/kernel/alloc.c | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 arch/i386/include/kernel/alloc.h create mode 100644 arch/i386/kernel/alloc.c (limited to 'arch') diff --git a/arch/i386/include/kernel/alloc.h b/arch/i386/include/kernel/alloc.h new file mode 100644 index 0000000..986bcc5 --- /dev/null +++ b/arch/i386/include/kernel/alloc.h @@ -0,0 +1,13 @@ +#ifndef I386_ALLOC_H +#define I386_ALLOC_H + +#include +#include +#include + +int alloc_init(struct mboot_info *info); +void mark_bitmap(uint32_t paddr, int present); +uint32_t pfa_alloc_frame(void); +void pfa_free(uint32_t paddr, int num_frames); + +#endif diff --git a/arch/i386/kernel/alloc.c b/arch/i386/kernel/alloc.c new file mode 100644 index 0000000..d2ddf79 --- /dev/null +++ b/arch/i386/kernel/alloc.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +extern uint32_t _bitmap_start; +static uint32_t *bm_start = &_bitmap_start; + +static struct mboot_info *info; + +int alloc_init(struct mboot_info *info) { + struct mboot_mmap_entry *mme; + for (uint32_t i = 0; i < info->mmap_length; i += sizeof(struct mboot_mmap_entry)) { + mme = (struct mboot_mmap_entry*)(info->mmap_addr + i); + if (mme->type != MBOOT_MEM_AVAILABLE) + mark_bitmap(mme->addr_low, 1); + } + return 0; +} + +void mark_bitmap(uint32_t paddr, int present) { + uint32_t index = (paddr & 0xFFFFF000) / 4096 / 32; + uint32_t bit = (paddr & 0xFFFFF000) / 4096 % 32; + bm_start[index] |= (present << bit); +} + +uint32_t pfa_alloc_frame(void) { + for (uint32_t i = 0; i < 4096; i++) { + uint32_t index = i / 32; + uint32_t bit = i % 32; + if ((bm_start[index] & (1 << bit)) == 0) { + mark_bitmap(i*4096, 1); + return i * 4096; + } + } + __asm__ volatile("hlt"); + return 0xFFFFFFFF; +} + +void pfa_free(uint32_t paddr, int num_frames) { + for (int i = 0; i < num_frames; i++) + mark_bitmap(paddr + (i*4096), 0); +} -- cgit v1.2.3