virtual page allocation

This commit is contained in:
nub31
2025-09-06 18:32:52 +02:00
parent 62680a05bc
commit 5f071104bc
4 changed files with 77 additions and 23 deletions

View File

@@ -13,8 +13,74 @@
#define PTE_USER (1ULL << 2)
#define PTE_PS (1ULL << 7)
#define BITMAP_PAGE_COUNT (ADDRES_SPACE_SIZE / PAGE_SIZE)
#define BITMAP_SIZE (BITMAP_PAGE_COUNT / 8)
static u8 page_bitmap[BITMAP_SIZE];
static u64 total_pages = 0;
static u64 free_pages = 0;
extern u64 pml4[];
void vmm_init()
{
// Mark first 32 pages (64mb) as unusable since it is reserved by the bootloader
// todo(nub31): This should be revisited. Maybe do a higher half kernel?
for (u64 page = 0; page < 32; page++)
{
if (page < BITMAP_PAGE_COUNT)
{
if (!(page_bitmap[page / 8] & (1 << (page % 8))))
{
page_bitmap[page / 8] |= (1 << (page % 8));
}
}
else
{
panic("Bitmap is not large enough to hold the bootloader reserved memory");
}
}
}
u64 vmm_alloc_address(size_t page_count)
{
for (size_t i = 0; i < BITMAP_SIZE; i++)
{
if (page_bitmap[i] != 0xFF)
{
for (int bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[i] & (1 << bit)))
{
page_bitmap[i] |= (1 << bit);
free_pages--;
return ((i * 8 + bit) * PAGE_SIZE);
}
}
}
}
return 0;
}
u64 vmm_free_address(u64 virtual_address, size_t page_count)
{
u64 page = virtual_address / PAGE_SIZE;
if (page < BITMAP_SIZE * 8)
{
if (page_bitmap[page / 8] & (1 << (page % 8)))
{
page_bitmap[page / 8] &= ~(1 << (page % 8));
free_pages++;
}
else
{
printf("Virtual address %x is already free", virtual_address);
panic("Failed to free virtual address");
}
}
}
static u64 create_2mb_pte(u64 physical_address, u32 flags)
{
if (physical_address & (PAGE_SIZE - 1))
@@ -97,16 +163,6 @@ u64 vmm_unmap(u64 virtual_address)
return physical_address;
}
u64 vmm_alloc_address(size_t page_count)
{
panic("not implemented");
}
u64 vmm_free_address(u64 virtual_address, size_t page_count)
{
panic("not implemented");
}
void* vmm_alloc(size_t page_count)
{
u64 virtual_address = vmm_alloc_address(page_count);