From 46bc97710446ee980551cbccd5eceea89b546503 Mon Sep 17 00:00:00 2001 From: nub31 Date: Sat, 6 Sep 2025 19:45:33 +0200 Subject: [PATCH] .. --- src/arch/x86_64/main.c | 1 - src/arch/x86_64/mem/pmm.c | 2 -- src/arch/x86_64/mem/pmm.h | 2 +- src/arch/x86_64/mem/vmm.c | 73 +++++++++++++++++++++++++++------------ src/arch/x86_64/mem/vmm.h | 6 +++- src/kernel/kernel.c | 2 +- 6 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 34c9382..0225e4c 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -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(); diff --git a/src/arch/x86_64/mem/pmm.c b/src/arch/x86_64/mem/pmm.c index d448bae..ffafa6a 100644 --- a/src/arch/x86_64/mem/pmm.c +++ b/src/arch/x86_64/mem/pmm.c @@ -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 { diff --git a/src/arch/x86_64/mem/pmm.h b/src/arch/x86_64/mem/pmm.h index 647ff42..ed2bcc9 100644 --- a/src/arch/x86_64/mem/pmm.h +++ b/src/arch/x86_64/mem/pmm.h @@ -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 diff --git a/src/arch/x86_64/mem/vmm.c b/src/arch/x86_64/mem/vmm.c index 26c7b1c..4bc963f 100644 --- a/src/arch/x86_64/mem/vmm.c +++ b/src/arch/x86_64/mem/vmm.c @@ -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) diff --git a/src/arch/x86_64/mem/vmm.h b/src/arch/x86_64/mem/vmm.h index d437fe5..7696254 100644 --- a/src/arch/x86_64/mem/vmm.h +++ b/src/arch/x86_64/mem/vmm.h @@ -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); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 7f0cfea..ec97f6f 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -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(); } \ No newline at end of file