diff options
-rw-r--r-- | arch/i386/include/kernel/alloc.h | 13 | ||||
-rw-r--r-- | arch/i386/kernel/alloc.c | 43 |
2 files changed, 56 insertions, 0 deletions
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 <kernel/multiboot.h> +#include <stdint.h> +#include <stddef.h> + +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 <kernel/alloc.h> +#include <kernel/paging.h> +#include <kernel/io.h> +#include <stdint.h> + +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); +} |