Files
Espresso/lib/mm/pmm.c

101 lines
2.2 KiB
C
Raw Normal View History

2025-10-20 21:57:30 -05:00
#include <string.h>
#include <stdio.h>
2025-05-28 14:41:02 -05:00
#include <mm/pmm.h>
2025-10-20 21:57:30 -05:00
#define MAX_PAGES (1024 * 1024) /* 4GB / 4KB */
static uint8_t bitmap[MAX_PAGES / 8] __attribute__((section(".pmm_bitmap")));
static size_t total_pages;
2025-05-28 14:41:02 -05:00
2025-10-20 21:57:30 -05:00
#define BITMAP_SET(i) (bitmap[(i) / 8] |= (1 << ((i) % 8)))
#define BITMAP_CLEAR(i) (bitmap[(i) / 8] &= ~(1 << ((i) % 8)))
#define BITMAP_TEST(i) (bitmap[(i) / 8] & (1 << ((i) % 8)))
2025-05-28 14:41:02 -05:00
2026-03-20 16:57:08 -05:00
extern uint32_t __kernel_start;
extern uint32_t __kernel_end;
2025-10-20 21:57:30 -05:00
void pmm_init(multiboot_info_t* mb)
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
#ifdef _DEBUG
printf("[ PMM ] Initializing physical memory manager...\n");
#endif
2025-05-28 14:41:02 -05:00
2025-10-20 21:57:30 -05:00
total_pages = MAX_PAGES;
for (uint32_t i = 0; i < (total_pages / 8); i++)
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
bitmap[i] = 0xFF;
2025-05-28 14:41:02 -05:00
}
2025-10-20 21:57:30 -05:00
multiboot_memory_map_t* mmap = (void*)(uintptr_t)mb->mmap_addr;
size_t entries = mb->mmap_length / sizeof(multiboot_memory_map_t);
for (size_t i = 0; i < entries; i++)
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
if (mmap[i].type == 1) /* usable */
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
uint64_t start = mmap[i].addr;
uint64_t end = start + mmap[i].len;
for (uint64_t addr = start; addr < end; addr += 0x1000)
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
if (addr >= 0x100000) /* skip below 1MB */
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
size_t idx = addr / 0x1000;
BITMAP_CLEAR(idx);
2025-05-28 14:41:02 -05:00
}
}
}
}
2025-10-20 21:57:30 -05:00
total_pages = MAX_PAGES;
2026-03-20 16:57:08 -05:00
uintptr_t start = (uintptr_t)&__kernel_start;
uintptr_t end = (uintptr_t)&__kernel_end;
start &= ~0xFFF;
end = (end + 0xFFF) & ~0xFFF;
for (uintptr_t addr = start; addr < end; addr += 0x1000)
{
size_t idx = addr / 0x1000;
BITMAP_SET(idx); // Mark kernel pages as USED
}
2025-10-20 21:57:30 -05:00
#ifdef _DEBUG
printf("[ PMM ] Physical memory manager initialized\n");
#endif
2025-05-28 14:41:02 -05:00
}
2025-10-20 21:57:30 -05:00
void* pmm_alloc_page(void)
{
for (uint32_t i = 0; i < total_pages; ++i)
2025-05-28 14:41:02 -05:00
{
2026-03-20 16:57:08 -05:00
void* page = (void*)(i * 4096);
if ((uintptr_t)page >= (uintptr_t)&__kernel_start &&
(uintptr_t)page < (uintptr_t)&__kernel_end)
{
printf("PMM allocating inside kernel at %x\n", page);
}
2025-10-20 21:57:30 -05:00
if (!BITMAP_TEST(i))
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
BITMAP_SET(i);
return (void*)(i * 4096);
2025-05-28 14:41:02 -05:00
}
}
2025-10-20 21:57:30 -05:00
printf("pmm_alloc_page(): No free page found!\n");
return NULL;
2025-05-28 14:41:02 -05:00
}
2025-10-20 21:57:30 -05:00
void pmm_free_page(void* addr)
2025-05-28 14:41:02 -05:00
{
2025-10-20 21:57:30 -05:00
size_t idx = (uintptr_t)addr / 0x1000;
BITMAP_CLEAR(idx);
2025-05-28 14:41:02 -05:00
}
2025-07-04 14:23:29 -05:00