This commit is contained in:
nub31
2025-09-06 19:45:33 +02:00
parent 5f071104bc
commit 46bc977104
6 changed files with 58 additions and 28 deletions

View File

@@ -23,7 +23,6 @@ void x86_64_main(u32 magic, multiboot_info_t* info)
idt_init();
remap_pic();
enable_interrupts();
pmm_init(info);
vmm_init();

View File

@@ -22,7 +22,6 @@ static size_t num_regions = 0;
#define BITMAP_SIZE (BITMAP_PAGE_COUNT / 8)
static u8 page_bitmap[BITMAP_SIZE];
static u64 total_pages = 0;
void pmm_init(multiboot_info_t* info)
{
@@ -71,7 +70,6 @@ void pmm_init(multiboot_info_t* info)
if (page < BITMAP_SIZE * 8)
{
page_bitmap[page / 8] &= ~(1 << (page % 8));
total_pages++;
}
else
{

View File

@@ -13,7 +13,7 @@
void pmm_init(multiboot_info_t* info);
// Low level function to allocate a 2mb physical page and return the physical address
// Return value 0 indicates out of memory
// A return value 0 indicates out of memory
u64 pmm_alloc();
// Low level function to free a 2mb physical page

View File

@@ -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)

View File

@@ -2,15 +2,19 @@
#include "std.h"
// Defines the theoretical max virtual memory space the kernel can allocate
// The value must be a multible of 8
#define ADDRES_SPACE_SIZE GiB(64)
void vmm_init();
// Allocates a free page aligned block of virtual addresses
// A return value 0 indicates that there were not blocks
// found which is large enought for the amount of pages requested
u64 vmm_alloc_address(size_t page_count);
// Frees a block of virtual addresses previously allocated via `vmm_alloc_address`
// Only use this function for pages mapped via `vmm_alloc_address`
u64 vmm_free_address(u64 virtual_address, size_t page_count);
void vmm_free_address(u64 virtual_address, size_t page_count);
// Low level function to map a virtual address to a physical address
void vmm_map(u64 physical_address, u64 virtual_address, u32 flags);

View File

@@ -4,8 +4,8 @@
void kernel_main()
{
arch_api.enable_interrupts();
printf("Welcome to nub OS :)\n");
printf("Kernel has exited\n");
arch_api.halt();
}