..
This commit is contained in:
@@ -17,8 +17,6 @@
|
||||
#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[];
|
||||
|
||||
@@ -37,48 +35,79 @@ void vmm_init()
|
||||
}
|
||||
else
|
||||
{
|
||||
panic("Bitmap is not large enough to hold the bootloader reserved memory");
|
||||
panic("Bitmap is not large enough to hold the bootloader reserved address space");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u64 vmm_alloc_address(size_t page_count)
|
||||
{
|
||||
for (size_t i = 0; i < BITMAP_SIZE; i++)
|
||||
size_t total_pages = BITMAP_PAGE_COUNT;
|
||||
|
||||
for (size_t start_page = 0; start_page <= total_pages - page_count; start_page++)
|
||||
{
|
||||
if (page_bitmap[i] != 0xFF)
|
||||
bool found_block = true;
|
||||
|
||||
for (size_t i = 0; i < page_count; i++)
|
||||
{
|
||||
for (int bit = 0; bit < 8; bit++)
|
||||
size_t page = start_page + i;
|
||||
size_t byte_index = page / 8;
|
||||
size_t bit_index = page % 8;
|
||||
|
||||
if (page_bitmap[byte_index] & (1 << bit_index))
|
||||
{
|
||||
if (!(page_bitmap[i] & (1 << bit)))
|
||||
{
|
||||
page_bitmap[i] |= (1 << bit);
|
||||
free_pages--;
|
||||
return ((i * 8 + bit) * PAGE_SIZE);
|
||||
}
|
||||
found_block = false;
|
||||
start_page = page;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_block)
|
||||
{
|
||||
for (size_t i = 0; i < page_count; i++)
|
||||
{
|
||||
size_t page = start_page + i;
|
||||
size_t byte_index = page / 8;
|
||||
size_t bit_index = page % 8;
|
||||
page_bitmap[byte_index] |= (1 << bit_index);
|
||||
}
|
||||
|
||||
return start_page * PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 vmm_free_address(u64 virtual_address, size_t page_count)
|
||||
void vmm_free_address(u64 virtual_address, size_t page_count)
|
||||
{
|
||||
u64 page = virtual_address / PAGE_SIZE;
|
||||
if (page < BITMAP_SIZE * 8)
|
||||
u64 start_page = virtual_address / PAGE_SIZE;
|
||||
if (start_page + page_count > BITMAP_PAGE_COUNT)
|
||||
{
|
||||
if (page_bitmap[page / 8] & (1 << (page % 8)))
|
||||
printf("Virtual address range exceeds bitmap bounds\n");
|
||||
panic("Failed to free virtual address");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < page_count; i++)
|
||||
{
|
||||
size_t page = start_page + i;
|
||||
size_t byte_index = page / 8;
|
||||
size_t bit_index = page % 8;
|
||||
|
||||
if (!(page_bitmap[byte_index] & (1 << bit_index)))
|
||||
{
|
||||
page_bitmap[page / 8] &= ~(1 << (page % 8));
|
||||
free_pages++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Virtual address %x is already free", virtual_address);
|
||||
printf("Virtual address 0x%x (page %u) is already free\n", virtual_address + (i * PAGE_SIZE), page);
|
||||
panic("Failed to free virtual address");
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < page_count; i++)
|
||||
{
|
||||
size_t page = start_page + i;
|
||||
size_t byte_index = page / 8;
|
||||
size_t bit_index = page % 8;
|
||||
page_bitmap[byte_index] &= ~(1 << bit_index);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 create_2mb_pte(u64 physical_address, u32 flags)
|
||||
|
||||
Reference in New Issue
Block a user