From 7223f52984f78fe6a82d00a5909c221c74064b90 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 13:30:39 +0530 Subject: [PATCH 01/20] Implement vaddr_t_to_ptr --- include/kernel/memmgt.h | 1 + src/kernel/memmgt.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/kernel/memmgt.h b/include/kernel/memmgt.h index dec4167..777d3c9 100644 --- a/include/kernel/memmgt.h +++ b/include/kernel/memmgt.h @@ -88,6 +88,7 @@ typedef uint64_t* paddr_t; vaddr_t get_vaddr_t_from_ptr (void* ptr); void* get_vaddr_hhdm (uint64_t phys_address); +void* vaddr_t_to_ptr (vaddr_t* virtual_addr); void init_memmgt (uint64_t, struct limine_memmap_response*); void walk_pagetable (void); diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index a305818..705fefa 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -44,6 +44,23 @@ vaddr_t get_vaddr_t_from_ptr (void* ptr) { return ret_vaddr; } +/*! + * Get a virtual pointer from a vaddr_t object. Automatically performs sign extension required in + * x86_64 + * @param virtual_addr the vaddr_t object + * @return corresponding virtual pointer + */ +inline void* vaddr_t_to_ptr (vaddr_t* virtual_addr) { + uint64_t ptr_64t = ((uint64_t)virtual_addr->pml4_index << 39) | + ((uint64_t)virtual_addr->pdpt_index << 30) | + ((uint64_t)virtual_addr->pd_index << 21) | + ((uint64_t)virtual_addr->pt_index << 12) | (uint64_t)virtual_addr->offset; + + if (ptr_64t & (1ULL << 47)) + ptr_64t |= 0xFFFF000000000000ULL; + return (void*)ptr_64t; +} + /*! * Convert a physical frame to vaddr pointer with HHDM mapping * @param phys_frame the physical frame From 14e256176a1af64a81de5e75032c3fb6de82bda2 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 13:39:22 +0530 Subject: [PATCH 02/20] vaddr_t should have uint16_t indices --- include/kernel/memmgt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/kernel/memmgt.h b/include/kernel/memmgt.h index 777d3c9..ae405d0 100644 --- a/include/kernel/memmgt.h +++ b/include/kernel/memmgt.h @@ -77,10 +77,10 @@ typedef struct { } memmap_bitmap; typedef struct { - uint8_t pml4_index; - uint8_t pdpt_index; - uint8_t pd_index; - uint8_t pt_index; + uint16_t pml4_index; + uint16_t pdpt_index; + uint16_t pd_index; + uint16_t pt_index; uint16_t offset; } vaddr_t; From f4ad4d5783bd421887944f649a71c19c2dd594ce Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 13:39:31 +0530 Subject: [PATCH 03/20] Add a simple alloc_vpage --- src/kernel/memmgt.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 705fefa..17c4472 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -248,6 +248,57 @@ void page_fault_handler (registers_t* registers) { __asm__ volatile ("hlt"); } +void* alloc_vpage (void) { + // all memory allocations are currently under one pml4 entry. this is 512 gb of memory, which + // should be plenty for literally any use case of COS. + pml4t_entry_t* pml4t_entry = &pml4_base_ptr[1]; + + for (uint16_t pdpt_idx = 0; pdpt_idx < 512; pdpt_idx++) { + pdpt_entry_t* pdpt_base_ptr = + (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); + pdpt_entry_t* pdpt_entry = &pdpt_base_ptr[pdpt_idx]; + + if (!pdpt_entry->present) { + paddr_t new_frame = alloc_ppage (); + pdpt_entry->present = 1; + pdpt_entry->read_write = 1; + pdpt_entry->frame_base_address = (uint64_t)new_frame / PAGE_SIZE; + } + + for (uint16_t pd_idx = 0; pd_idx < 512; pd_idx++) { + pd_entry_t* pd_base_ptr = + (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); + pd_entry_t* pd_entry = &pd_base_ptr[pd_idx]; + + if (!pd_entry->present) { + paddr_t new_frame = alloc_ppage (); + pd_entry->present = 1; + pd_entry->rw = 1; + pd_entry->frame_base_address = (uint64_t)new_frame / PAGE_SIZE; + } + + for (uint16_t pt_idx = 0; pt_idx < 512; pt_idx++) { + pt_entry_t* pt_base_ptr = + (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); + pt_entry_t* pt_entry = &pt_base_ptr[pt_idx]; + + if (pt_entry->present) + continue; + + paddr_t new_frame = alloc_ppage (); + pt_entry->present = 1; + pt_entry->rw = 1; + pt_entry->frame_base_address = (uint64_t)new_frame / PAGE_SIZE; + + vaddr_t virtual_addr = {1, pdpt_idx, pd_idx, pt_idx, 0}; + return vaddr_t_to_ptr (&virtual_addr); + } + } + } + + return NULL; +} + /*! * Initializes the memory management subsystem. * Sets the base pointer for the PML4 table and stores the HHDM offset. From 8dcaa4f86bb5fd7e0f7c9ed3f6720eae150240ba Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 13:43:20 +0530 Subject: [PATCH 04/20] Fix some mistypes --- src/kernel/memmgt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 17c4472..2638e1f 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -252,6 +252,7 @@ void* alloc_vpage (void) { // all memory allocations are currently under one pml4 entry. this is 512 gb of memory, which // should be plenty for literally any use case of COS. pml4t_entry_t* pml4t_entry = &pml4_base_ptr[1]; + if (!pml4t_entry->present) return NULL; for (uint16_t pdpt_idx = 0; pdpt_idx < 512; pdpt_idx++) { pdpt_entry_t* pdpt_base_ptr = @@ -262,7 +263,7 @@ void* alloc_vpage (void) { paddr_t new_frame = alloc_ppage (); pdpt_entry->present = 1; pdpt_entry->read_write = 1; - pdpt_entry->frame_base_address = (uint64_t)new_frame / PAGE_SIZE; + pdpt_entry->pd_base_address = (uint64_t)new_frame / PAGE_SIZE; } for (uint16_t pd_idx = 0; pd_idx < 512; pd_idx++) { @@ -274,7 +275,7 @@ void* alloc_vpage (void) { paddr_t new_frame = alloc_ppage (); pd_entry->present = 1; pd_entry->rw = 1; - pd_entry->frame_base_address = (uint64_t)new_frame / PAGE_SIZE; + pd_entry->pt_base_address = (uint64_t)new_frame / PAGE_SIZE; } for (uint16_t pt_idx = 0; pt_idx < 512; pt_idx++) { From e37b92326ac989e4f3ed3417bafbc5fa877ef133 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 14:48:25 +0530 Subject: [PATCH 05/20] Revamp to a smarter alloc system + add alloc_vpages --- src/kernel/memmgt.c | 190 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 158 insertions(+), 32 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 2638e1f..a79ce9b 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -248,58 +248,184 @@ void page_fault_handler (registers_t* registers) { __asm__ volatile ("hlt"); } -void* alloc_vpage (void) { +/*! + * Check if vaddr a is strictly less than vaddr b + * @param a first vaddr + * @param b second vaddr + * @return true if a lies before b, false otherwise + */ +bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) { + if (a->pml4_index == b->pml4_index) { + if (a->pdpt_index == b->pdpt_index) { + if (a->pd_index == b->pd_index) { + if (a->pt_index == b->pt_index) return a->offset < b->offset; + return a->pt_index < b->pt_index; + } + return a->pd_index < b->pd_index; + } + return a->pdpt_index < b->pdpt_index; + } + return a->pml4_index < b->pml4_index; +} + +/*! + * Allocate all virtual pages in given range (inclusive). Needs physical memory to be allocated. + * @param first first virtual address in range + * @param last last virtual address in range + * @param base_addr base address of physical memory of corresponding size + */ +void alloc_all_vpages_in_range (vaddr_t first, vaddr_t last, paddr_t base_addr) { + uint64_t phys_base_track = (uint64_t)base_addr; + pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; + + vaddr_t current = first; + + while (true) { + pdpt_entry_t* pdpt_base = (pdpt_entry_t*)get_vaddr_from_frame(pml4t_entry->pdpt_base_address); + pdpt_entry_t* pdpt_entry = &pdpt_base[current.pdpt_index]; + + if (!pdpt_entry->present) { + paddr_t new_table = alloc_ppage(); + pdpt_entry->present = 1; + pdpt_entry->read_write = 1; + pdpt_entry->pd_base_address = (uint64_t)new_table / PAGE_SIZE; + memset(get_vaddr_from_frame((uint64_t)new_table / PAGE_SIZE), 0, PAGE_SIZE); + } + + pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame(pdpt_entry->pd_base_address); + pd_entry_t* pd_entry = &pd_base[current.pd_index]; + + if (!pd_entry->present) { + paddr_t new_table = alloc_ppage(); + pd_entry->present = 1; + pd_entry->rw = 1; + pd_entry->pt_base_address = (uint64_t)new_table / PAGE_SIZE; + memset(get_vaddr_from_frame((uint64_t)new_table / PAGE_SIZE), 0, PAGE_SIZE); + } + + pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame(pd_entry->pt_base_address); + pt_entry_t* pt_entry = &pt_base[current.pt_index]; + + pt_entry->present = 1; + pt_entry->rw = 1; + pt_entry->frame_base_address = phys_base_track / PAGE_SIZE; + phys_base_track += PAGE_SIZE; + + if (!is_vaddr_t_lt(¤t, &first)) break; + + current.pt_index++; + if (current.pt_index >= 512) { + current.pt_index = 0; + current.pd_index++; + if (current.pd_index >= 512) { + current.pd_index = 0; + current.pdpt_index++; + } + } + } +} + +/*! + * Allocate multiple consecutive virtual pages + * @param count number of consecutive pages to allocate + * @return base virtual address of allocated pages + */ +void* alloc_vpages (size_t req_count) { // all memory allocations are currently under one pml4 entry. this is 512 gb of memory, which // should be plenty for literally any use case of COS. pml4t_entry_t* pml4t_entry = &pml4_base_ptr[1]; if (!pml4t_entry->present) return NULL; - for (uint16_t pdpt_idx = 0; pdpt_idx < 512; pdpt_idx++) { - pdpt_entry_t* pdpt_base_ptr = - (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); - pdpt_entry_t* pdpt_entry = &pdpt_base_ptr[pdpt_idx]; + size_t count_so_far = 0; + uint64_t start_page_idx = 0; - if (!pdpt_entry->present) { - paddr_t new_frame = alloc_ppage (); - pdpt_entry->present = 1; - pdpt_entry->read_write = 1; - pdpt_entry->pd_base_address = (uint64_t)new_frame / PAGE_SIZE; - } + for (uint64_t i = 0; i < 512ull * 512ull * 512ull;) { + uint16_t pdpt_idx = (i >> 18) & 0x1FF; + uint16_t pd_idx = (i >> 9) & 0x1FF; + uint16_t pt_idx = i & 0x1FF; - for (uint16_t pd_idx = 0; pd_idx < 512; pd_idx++) { - pd_entry_t* pd_base_ptr = - (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); - pd_entry_t* pd_entry = &pd_base_ptr[pd_idx]; + pdpt_entry_t* pdpt_base = (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); + pdpt_entry_t* pdpt_entry = &pdpt_base[pdpt_idx]; - if (!pd_entry->present) { - paddr_t new_frame = alloc_ppage (); - pd_entry->present = 1; - pd_entry->rw = 1; - pd_entry->pt_base_address = (uint64_t)new_frame / PAGE_SIZE; + if (!pdpt_entry->present) { + // we found 512*512 consecutive free pages! + if (count_so_far == 0) start_page_idx = i; + uint64_t pages_left = 512ull*512ull - (i % 512ull*512ull); // just in case + + if (count_so_far + pages_left >= req_count) { + count_so_far = req_count; + break; } - for (uint16_t pt_idx = 0; pt_idx < 512; pt_idx++) { - pt_entry_t* pt_base_ptr = - (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); - pt_entry_t* pt_entry = &pt_base_ptr[pt_idx]; + count_so_far += pages_left; + i += pages_left; + continue; + } - if (pt_entry->present) - continue; + pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); + pd_entry_t* pd_entry = &pd_base[pd_idx]; - paddr_t new_frame = alloc_ppage (); - pt_entry->present = 1; - pt_entry->rw = 1; - pt_entry->frame_base_address = (uint64_t)new_frame / PAGE_SIZE; + if (!pd_entry->present) { + // we found 512 consecutive free pages! + if (count_so_far == 0) start_page_idx = i; + uint64_t pages_left = 512ull - (i % 512ull); // just in case - vaddr_t virtual_addr = {1, pdpt_idx, pd_idx, pt_idx, 0}; - return vaddr_t_to_ptr (&virtual_addr); + if (count_so_far + pages_left >= req_count) { + count_so_far = req_count; + break; } + + count_so_far += pages_left; + i += pages_left; + continue; } + + pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); + pt_entry_t* pt_entry = &pt_base[pt_idx]; + + if (pt_entry->present) { + count_so_far = 0; + i++; + } else { + if (count_so_far == 0) start_page_idx = i; + count_so_far++; + if (count_so_far == req_count) break; + i++ + } + } + + if (count_so_far == req_count) { + paddr_t base_physical = alloc_ppages (req_count); + if (base_physical == NULL) return NULL; // no more physical memory + + vaddr_t first_vaddr = { + 1, + (start_page_idx >> 18) & 0x1FF, + (start_page_idx >> 9) & 0x1FF, + start_page_idx & 0x1FF, + 0 + }; + vaddr_t last_vaddr = { + 1, + ((start_page_idx + req_count - 1) >> 18) & 0x1FF, + ((start_page_idx + req_count - 1) >> 9) & 0x1FF, + (start_page_idx + req_count - 1) & 0x1FF, + 0 + }; + + alloc_all_vpages_in_range (first_vaddr, last_vaddr, base_physical); + return vaddr_t_to_ptr (&first_vaddr); } return NULL; } +/*! + * Allocate one virtual page + * @return base virtual address of allocated page + */ +void* alloc_vpage (void) { return alloc_vpages(1); } + /*! * Initializes the memory management subsystem. * Sets the base pointer for the PML4 table and stores the HHDM offset. From 5975a1b7e6b4b6e2cbefb8664af429f22d64bfce Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:00:47 +0530 Subject: [PATCH 06/20] Format + add free_all_vpages_in_range --- src/kernel/memmgt.c | 260 ++++++++++++++++++++++++++++++-------------- 1 file changed, 178 insertions(+), 82 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index a79ce9b..1ae5830 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -258,7 +258,8 @@ bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) { if (a->pml4_index == b->pml4_index) { if (a->pdpt_index == b->pdpt_index) { if (a->pd_index == b->pd_index) { - if (a->pt_index == b->pt_index) return a->offset < b->offset; + if (a->pt_index == b->pt_index) + return a->offset < b->offset; return a->pt_index < b->pt_index; } return a->pd_index < b->pd_index; @@ -275,54 +276,56 @@ bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) { * @param base_addr base address of physical memory of corresponding size */ void alloc_all_vpages_in_range (vaddr_t first, vaddr_t last, paddr_t base_addr) { - uint64_t phys_base_track = (uint64_t)base_addr; - pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; - - vaddr_t current = first; - - while (true) { - pdpt_entry_t* pdpt_base = (pdpt_entry_t*)get_vaddr_from_frame(pml4t_entry->pdpt_base_address); - pdpt_entry_t* pdpt_entry = &pdpt_base[current.pdpt_index]; - - if (!pdpt_entry->present) { - paddr_t new_table = alloc_ppage(); - pdpt_entry->present = 1; - pdpt_entry->read_write = 1; - pdpt_entry->pd_base_address = (uint64_t)new_table / PAGE_SIZE; - memset(get_vaddr_from_frame((uint64_t)new_table / PAGE_SIZE), 0, PAGE_SIZE); - } - - pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame(pdpt_entry->pd_base_address); - pd_entry_t* pd_entry = &pd_base[current.pd_index]; - - if (!pd_entry->present) { - paddr_t new_table = alloc_ppage(); - pd_entry->present = 1; - pd_entry->rw = 1; - pd_entry->pt_base_address = (uint64_t)new_table / PAGE_SIZE; - memset(get_vaddr_from_frame((uint64_t)new_table / PAGE_SIZE), 0, PAGE_SIZE); - } - - pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame(pd_entry->pt_base_address); - pt_entry_t* pt_entry = &pt_base[current.pt_index]; - - pt_entry->present = 1; - pt_entry->rw = 1; - pt_entry->frame_base_address = phys_base_track / PAGE_SIZE; - phys_base_track += PAGE_SIZE; - - if (!is_vaddr_t_lt(¤t, &first)) break; - - current.pt_index++; - if (current.pt_index >= 512) { - current.pt_index = 0; - current.pd_index++; - if (current.pd_index >= 512) { - current.pd_index = 0; - current.pdpt_index++; - } - } - } + uint64_t phys_base_track = (uint64_t)base_addr; + pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; + + vaddr_t current = first; + + while (true) { + pdpt_entry_t* pdpt_base = + (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); + pdpt_entry_t* pdpt_entry = &pdpt_base[current.pdpt_index]; + + if (!pdpt_entry->present) { + paddr_t new_table = alloc_ppage (); + pdpt_entry->present = 1; + pdpt_entry->read_write = 1; + pdpt_entry->pd_base_address = (uint64_t)new_table / PAGE_SIZE; + memset (get_vaddr_from_frame ((uint64_t)new_table / PAGE_SIZE), 0, PAGE_SIZE); + } + + pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); + pd_entry_t* pd_entry = &pd_base[current.pd_index]; + + if (!pd_entry->present) { + paddr_t new_table = alloc_ppage (); + pd_entry->present = 1; + pd_entry->rw = 1; + pd_entry->pt_base_address = (uint64_t)new_table / PAGE_SIZE; + memset (get_vaddr_from_frame ((uint64_t)new_table / PAGE_SIZE), 0, PAGE_SIZE); + } + + pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); + pt_entry_t* pt_entry = &pt_base[current.pt_index]; + + pt_entry->present = 1; + pt_entry->rw = 1; + pt_entry->frame_base_address = phys_base_track / PAGE_SIZE; + phys_base_track += PAGE_SIZE; + + if (!is_vaddr_t_lt (¤t, &first)) + break; + + current.pt_index++; + if (current.pt_index >= 512) { + current.pt_index = 0; + current.pd_index++; + if (current.pd_index >= 512) { + current.pd_index = 0; + current.pdpt_index++; + } + } + } } /*! @@ -334,7 +337,8 @@ void* alloc_vpages (size_t req_count) { // all memory allocations are currently under one pml4 entry. this is 512 gb of memory, which // should be plenty for literally any use case of COS. pml4t_entry_t* pml4t_entry = &pml4_base_ptr[1]; - if (!pml4t_entry->present) return NULL; + if (!pml4t_entry->present) + return NULL; size_t count_so_far = 0; uint64_t start_page_idx = 0; @@ -344,13 +348,15 @@ void* alloc_vpages (size_t req_count) { uint16_t pd_idx = (i >> 9) & 0x1FF; uint16_t pt_idx = i & 0x1FF; - pdpt_entry_t* pdpt_base = (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); - pdpt_entry_t* pdpt_entry = &pdpt_base[pdpt_idx]; + pdpt_entry_t* pdpt_base = + (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); + pdpt_entry_t* pdpt_entry = &pdpt_base[pdpt_idx]; if (!pdpt_entry->present) { // we found 512*512 consecutive free pages! - if (count_so_far == 0) start_page_idx = i; - uint64_t pages_left = 512ull*512ull - (i % 512ull*512ull); // just in case + if (count_so_far == 0) + start_page_idx = i; + uint64_t pages_left = 512ull * 512ull - (i % 512ull * 512ull); // just in case if (count_so_far + pages_left >= req_count) { count_so_far = req_count; @@ -362,12 +368,13 @@ void* alloc_vpages (size_t req_count) { continue; } - pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); - pd_entry_t* pd_entry = &pd_base[pd_idx]; + pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); + pd_entry_t* pd_entry = &pd_base[pd_idx]; if (!pd_entry->present) { // we found 512 consecutive free pages! - if (count_so_far == 0) start_page_idx = i; + if (count_so_far == 0) + start_page_idx = i; uint64_t pages_left = 512ull - (i % 512ull); // just in case if (count_so_far + pages_left >= req_count) { @@ -380,41 +387,35 @@ void* alloc_vpages (size_t req_count) { continue; } - pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); - pt_entry_t* pt_entry = &pt_base[pt_idx]; + pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); + pt_entry_t* pt_entry = &pt_base[pt_idx]; if (pt_entry->present) { count_so_far = 0; i++; } else { - if (count_so_far == 0) start_page_idx = i; + if (count_so_far == 0) + start_page_idx = i; count_so_far++; - if (count_so_far == req_count) break; + if (count_so_far == req_count) + break; i++ } } if (count_so_far == req_count) { - paddr_t base_physical = alloc_ppages (req_count); - if (base_physical == NULL) return NULL; // no more physical memory - - vaddr_t first_vaddr = { - 1, - (start_page_idx >> 18) & 0x1FF, - (start_page_idx >> 9) & 0x1FF, - start_page_idx & 0x1FF, - 0 - }; - vaddr_t last_vaddr = { - 1, - ((start_page_idx + req_count - 1) >> 18) & 0x1FF, - ((start_page_idx + req_count - 1) >> 9) & 0x1FF, - (start_page_idx + req_count - 1) & 0x1FF, - 0 - }; - - alloc_all_vpages_in_range (first_vaddr, last_vaddr, base_physical); - return vaddr_t_to_ptr (&first_vaddr); + paddr_t base_physical = alloc_ppages (req_count); + if (base_physical == NULL) + return NULL; // no more physical memory + + vaddr_t first_vaddr = {1, (start_page_idx >> 18) & 0x1FF, (start_page_idx >> 9) & 0x1FF, + start_page_idx & 0x1FF, 0}; + vaddr_t last_vaddr = {1, ((start_page_idx + req_count - 1) >> 18) & 0x1FF, + ((start_page_idx + req_count - 1) >> 9) & 0x1FF, + (start_page_idx + req_count - 1) & 0x1FF, 0}; + + alloc_all_vpages_in_range (first_vaddr, last_vaddr, base_physical); + return vaddr_t_to_ptr (&first_vaddr); } return NULL; @@ -424,7 +425,102 @@ void* alloc_vpages (size_t req_count) { * Allocate one virtual page * @return base virtual address of allocated page */ -void* alloc_vpage (void) { return alloc_vpages(1); } +void* alloc_vpage (void) { return alloc_vpages (1); } + +/*! + * Check if page structure is empty + * @param table_vaddr virtual address of the page structure + * @return whether it is empty + */ +static bool is_table_empty (void* table_vaddr) { + uint64_t* entries = (uint64_t*)table_vaddr; + for (int i = 0; i < 512; i++) + if (entries[i] & 1) + return false; + return true; +} + +/*! + * Frees all virtual pages in a given range (inclusive) + * @param first first virtual page in range + * @param last last virtual page in range + */ +void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { + if (first.pml4_index == 1) { + write_serial_str ("free_all_vpages_in_range called for pml4_index that is not 1!"); + return; + } + + pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; + if (!pml4t_entry->present) + return; + + vaddr_t current = first; + + while (true) { + pdpt_entry_t* pdpt_base = + (pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address); + pdpt_entry_t* pdpt_entry = &pdpt_base[current.pdpt_index]; + + if (pdpt_entry->present) { + pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address); + pd_entry_t* pd_entry = &pd_base[current.pd_index]; + + if (pd_entry->present) { + pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); + pt_entry_t* pt_entry = &pt_base[current.pt_index]; + + if (pt_entry->present) { + pt_entry->present = 0; + pt_entry->frame_base_address = 0; + + void* current_vaddr_ptr = vaddr_t_to_ptr (¤t); + __asm__ volatile ("invlpg (%0)" : : "r"(current_vaddr_ptr) : "memory"); + + // --- GARBAGE COLLECTION --- + // We only need to check if a table is empty when we cross its boundary OR on + // our final page. + if ((current.pt_index == 511) || (!is_vaddr_t_lt (¤t, &last))) { + if (is_table_empty (pt_base)) { + free_ppage ((void*)(pd_entry->pt_base_address * PAGE_SIZE)); + pd_entry->present = 0; + pd_entry->pt_base_address = 0; + + if ((current.pd_index == 511) || + (!is_vaddr_t_lt (¤t, &last)) && is_table_empty (pd_base)) { + free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE)); + pdpt_entry->present = 0; + pdpt_entry->pd_base_address = 0; + + if ((current.pdpt_index == 511) || + (!is_vaddr_t_lt (¤t, &last)) && + is_table_empty (pdpt_base)) { + free_ppage ( + (void*)(pml4t_entry->pdpt_base_address * PAGE_SIZE)); + pml4t_entry->present = 0; + pml4t_entry->pdpt_base_address = 0; + } + } + } + } + } + } + } + + if (!is_vaddr_t_lt (¤t, &last)) + break; + + current.pt_index++; + if (current.pt_index >= 512) { + current.pt_index = 0; + current.pd_index++; + if (current.pd_index >= 512) { + current.pd_index = 0; + current.pdpt_index++; + } + } + } +} /*! * Initializes the memory management subsystem. From a9658f2443a87ab511dfd5704b7f0aedc495a60c Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:04:54 +0530 Subject: [PATCH 07/20] Bugfix + quell some warnings --- src/kernel/memmgt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 1ae5830..cb82d16 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -5,7 +5,7 @@ #include #include -#define PAGE_SIZE 4096 +#define PAGE_SIZE 4096ull pml4t_entry_t* pml4_base_ptr = NULL; uint64_t hhdm_offset = 0; @@ -313,7 +313,7 @@ void alloc_all_vpages_in_range (vaddr_t first, vaddr_t last, paddr_t base_addr) pt_entry->frame_base_address = phys_base_track / PAGE_SIZE; phys_base_track += PAGE_SIZE; - if (!is_vaddr_t_lt (¤t, &first)) + if (!is_vaddr_t_lt (¤t, &last)) break; current.pt_index++; @@ -399,7 +399,7 @@ void* alloc_vpages (size_t req_count) { count_so_far++; if (count_so_far == req_count) break; - i++ + i++; } } @@ -486,15 +486,15 @@ void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { pd_entry->present = 0; pd_entry->pt_base_address = 0; - if ((current.pd_index == 511) || - (!is_vaddr_t_lt (¤t, &last)) && is_table_empty (pd_base)) { + if (((current.pd_index == 511) || (!is_vaddr_t_lt (¤t, &last))) && + is_table_empty (pd_base)) { free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE)); pdpt_entry->present = 0; pdpt_entry->pd_base_address = 0; - if ((current.pdpt_index == 511) || - (!is_vaddr_t_lt (¤t, &last)) && - is_table_empty (pdpt_base)) { + if (((current.pdpt_index == 511) || + (!is_vaddr_t_lt (¤t, &last))) && + is_table_empty (pdpt_base)) { free_ppage ( (void*)(pml4t_entry->pdpt_base_address * PAGE_SIZE)); pml4t_entry->present = 0; From 4f22f690f05071ba607172be1c006ad74ffe8562 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:09:15 +0530 Subject: [PATCH 08/20] Minor readability improvement --- src/kernel/memmgt.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index cb82d16..b3acd1b 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -480,26 +480,23 @@ void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { // --- GARBAGE COLLECTION --- // We only need to check if a table is empty when we cross its boundary OR on // our final page. - if ((current.pt_index == 511) || (!is_vaddr_t_lt (¤t, &last))) { - if (is_table_empty (pt_base)) { - free_ppage ((void*)(pd_entry->pt_base_address * PAGE_SIZE)); - pd_entry->present = 0; - pd_entry->pt_base_address = 0; - - if (((current.pd_index == 511) || (!is_vaddr_t_lt (¤t, &last))) && - is_table_empty (pd_base)) { - free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE)); - pdpt_entry->present = 0; - pdpt_entry->pd_base_address = 0; - - if (((current.pdpt_index == 511) || - (!is_vaddr_t_lt (¤t, &last))) && - is_table_empty (pdpt_base)) { - free_ppage ( - (void*)(pml4t_entry->pdpt_base_address * PAGE_SIZE)); - pml4t_entry->present = 0; - pml4t_entry->pdpt_base_address = 0; - } + bool on_final_pg = !is_vaddr_t_lt (¤t, &last); + if (((current.pt_index == 511) || on_final_pg) && is_table_empty (pt_base)) { + free_ppage ((void*)(pd_entry->pt_base_address * PAGE_SIZE)); + pd_entry->present = 0; + pd_entry->pt_base_address = 0; + + if (((current.pd_index == 511) || on_final_pg) && + is_table_empty (pd_base)) { + free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE)); + pdpt_entry->present = 0; + pdpt_entry->pd_base_address = 0; + + if (((current.pdpt_index == 511) || on_final_pg) && + is_table_empty (pdpt_base)) { + free_ppage ((void*)(pml4t_entry->pdpt_base_address * PAGE_SIZE)); + pml4t_entry->present = 0; + pml4t_entry->pdpt_base_address = 0; } } } From 161156c34fb2a75aa513e5d21900debcdc1e88bd Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:11:10 +0530 Subject: [PATCH 09/20] Add free for vpages --- src/kernel/memmgt.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index b3acd1b..a5a5d59 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -519,6 +519,36 @@ void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { } } +/*! + * Free multiple consecutive virtual pages= + * @param ptr virtual address of the first page to free + * @param count number of consecutive pages to free + */ +void free_vpages (void* ptr, size_t count) { + if (ptr == NULL || count == 0) + return; + + void* phys_base = get_paddr (ptr); + if (phys_base == NULL) + return; + + free_ppages (phys_base, count); + + uint64_t start_ptr_64t = (uint64_t)ptr; + uint64_t last_ptr_64t = start_ptr_64t + ((count - 1) * PAGE_SIZE); + + vaddr_t first_vaddr = get_vaddr_t_from_ptr ((void*)start_ptr_64t); + vaddr_t last_vaddr = get_vaddr_t_from_ptr ((void*)last_ptr_64t); + + free_all_vpages_in_range (first_vaddr, last_vaddr); +} + +/*! + * Free single virtual page + * @param ptr virtual address of the page to free + */ +void free_vpage (void* ptr) { free_vpages (ptr, 1); } + /*! * Initializes the memory management subsystem. * Sets the base pointer for the PML4 table and stores the HHDM offset. From fe5bc072350bace19bd93026acea55620aea8949 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:13:25 +0530 Subject: [PATCH 10/20] Move the check for pml4 index to free_vpages --- src/kernel/memmgt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index a5a5d59..239d61c 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -446,11 +446,6 @@ static bool is_table_empty (void* table_vaddr) { * @param last last virtual page in range */ void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { - if (first.pml4_index == 1) { - write_serial_str ("free_all_vpages_in_range called for pml4_index that is not 1!"); - return; - } - pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; if (!pml4t_entry->present) return; @@ -528,6 +523,12 @@ void free_vpages (void* ptr, size_t count) { if (ptr == NULL || count == 0) return; + vaddr_t vaddr = get_vaddr_t_from_ptr (ptr); + if (vaddr.pml4_index != 1) { + write_serial_str ("free_vpages called for pml4_index that is not 1!"); + return; + } + void* phys_base = get_paddr (ptr); if (phys_base == NULL) return; From 989abc37e873639b3f269ad91469d77c258f51fc Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:19:07 +0530 Subject: [PATCH 11/20] Switch to novel vmm for malloc --- src/kernel/memmgt.c | 45 ++------------------------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 239d61c..e6c04c1 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -724,53 +724,12 @@ int liballoc_unlock () { return 0; } -void* liballoc_alloc (size_t count) { - pml4t_entry_t* pml4t_entry = &pml4_base_ptr[1]; - if (!pml4t_entry->present) - return NULL; - pdpt_entry_t* pdpt_entry = - &((pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address))[0]; - if (!pdpt_entry->present) - return NULL; - pd_entry_t* pd_entry = &((pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address))[0]; - if (!pd_entry->present) - return NULL; - pt_entry_t* pt_base_ptr = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); - - return try_assign_pt (pt_base_ptr, count); -} +void* liballoc_alloc (size_t count) { return alloc_vpages (count); } int liballoc_free (void* ptr, size_t count) { if (is_locked) return -7; - if (get_paddr (ptr) == NULL) - return -1; - - vaddr_t vaddr = get_vaddr_t_from_ptr (ptr); - - pml4t_entry_t* pml4t_entry = &pml4_base_ptr[vaddr.pml4_index]; - if (!pml4t_entry->present || vaddr.pml4_index != 1) - return -2; - pdpt_entry_t* pdpt_entry = - &((pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address))[vaddr.pdpt_index]; - if (!pdpt_entry->present || vaddr.pdpt_index != 0) - return -3; - pd_entry_t* pd_entry = - &((pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address))[vaddr.pd_index]; - if (!pd_entry->present || vaddr.pd_index != 0) - return -4; - pt_entry_t* pt_base_ptr = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address); - - for (size_t i = 0; i < count; i++) { - if (i + vaddr.pt_index >= 512) - return -5; // out of bounds - - pt_entry_t* pt_entry = &pt_base_ptr[i + vaddr.pt_index]; - if (!pt_entry->allocated) - return -6; - - pt_entry->allocated = 0; - } + free_vpages (ptr, count); return 0; } \ No newline at end of file From a23f18b46026a4229422ae06651f5f1f7fedc716 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:19:56 +0530 Subject: [PATCH 12/20] Deprecate try_assign_pt --- src/kernel/memmgt.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index e6c04c1..3fda71b 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -691,29 +691,6 @@ LIBALLOC FUNCTION IMPLEMENTATIONS */ -void* try_assign_pt (pt_entry_t* pt_base_ptr, size_t count) { - int free_count = 0; - for (int i = 0; i < 512; i++) { - if (pt_base_ptr[i].allocated) { - free_count = 0; - continue; - } else { - free_count++; - if ((size_t)free_count == count) { - int init_idx = i - count + 1; - - for (int j = init_idx; j <= i; j++) { - pt_base_ptr[j].allocated = 1; - } - - void* alloc_addr = (void*)((1ll << 39) | ((uint64_t)init_idx << 12)); - return alloc_addr; - } - } - } - return NULL; -} - int liballoc_lock () { is_locked = true; return 0; From 19669565219e0ff75f3a343b14a31bca0b87a742 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:20:46 +0530 Subject: [PATCH 13/20] Remove now unused 'allocated' flag --- include/kernel/memmgt.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/kernel/memmgt.h b/include/kernel/memmgt.h index ae405d0..6046d07 100644 --- a/include/kernel/memmgt.h +++ b/include/kernel/memmgt.h @@ -62,8 +62,7 @@ typedef struct { uint64_t dirty : 1; uint64_t pat : 1; uint64_t global : 1; - uint64_t allocated : 1; - uint64_t available1 : 2; + uint64_t available1 : 3; uint64_t frame_base_address : 40; uint64_t available2 : 11; uint64_t nex : 1; From 5d6cc7fc27c005e3362a98a24ffeb242d22f65db Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:31:27 +0530 Subject: [PATCH 14/20] Remove most of init_memmgt --- src/kernel/memmgt.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 3fda71b..2846d45 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -566,31 +566,12 @@ void init_memmgt (uint64_t p_hhdm_offset, struct limine_memmap_response* memmap_ // set up bitmap for physical page allocation init_physical_bitmap (memmap_response); - paddr_t phys_tables = alloc_ppages (3); - paddr_t initial_frames = alloc_ppages (512); + paddr_t pdpt_frame = alloc_ppage(); + memset(get_vaddr_from_frame((uint64_t)pdpt_frame/PAGE_SIZE), 0, PAGE_SIZE); - pdpt_entry_t* pdpt = (pdpt_entry_t*)get_vaddr_from_frame ((uint64_t)phys_tables / PAGE_SIZE); - pd_entry_t* pd = (pd_entry_t*)get_vaddr_from_frame (((uint64_t)phys_tables / PAGE_SIZE) + 1); - pt_entry_t* pt = (pt_entry_t*)get_vaddr_from_frame (((uint64_t)phys_tables / PAGE_SIZE) + 2); - - pdpt[0].present = 1; - pdpt[0].read_write = 1; - pdpt[0].pd_base_address = (((uint64_t)phys_tables) / PAGE_SIZE) + 1; - - pd[0].present = 1; - pd[0].rw = 1; - pd[0].pt_base_address = (((uint64_t)phys_tables) / PAGE_SIZE) + 2; - - for (int i = 0; i < 512; i++) { - pt[i].present = 1; - pt[i].rw = 1; - pt[i].frame_base_address = (((uint64_t)initial_frames / PAGE_SIZE) + i); - } - - // initialise PML4T idx 1 and PDPT idx 0 for our page assignments pml4_base_ptr[1].present = 1; pml4_base_ptr[1].read_write = 1; - pml4_base_ptr[1].pdpt_base_address = ((uint64_t)phys_tables) / PAGE_SIZE; + pml4_base_ptr[1].pdpt_base_address = ((uint64_t)pdpt_frame) / PAGE_SIZE; } /*! From 2e3243143f603fa38a5264e8ca3743db634e9662 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:33:39 +0530 Subject: [PATCH 15/20] Don't delete the pdpt even if it is empty --- src/kernel/memmgt.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 2846d45..4e5d863 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -486,13 +486,6 @@ void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE)); pdpt_entry->present = 0; pdpt_entry->pd_base_address = 0; - - if (((current.pdpt_index == 511) || on_final_pg) && - is_table_empty (pdpt_base)) { - free_ppage ((void*)(pml4t_entry->pdpt_base_address * PAGE_SIZE)); - pml4t_entry->present = 0; - pml4t_entry->pdpt_base_address = 0; - } } } } From 25bab24cd96689caac5da3b4d4db3f1e2a1cc256 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:33:50 +0530 Subject: [PATCH 16/20] Format --- src/kernel/memmgt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index 4e5d863..bf857a4 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -559,8 +559,8 @@ void init_memmgt (uint64_t p_hhdm_offset, struct limine_memmap_response* memmap_ // set up bitmap for physical page allocation init_physical_bitmap (memmap_response); - paddr_t pdpt_frame = alloc_ppage(); - memset(get_vaddr_from_frame((uint64_t)pdpt_frame/PAGE_SIZE), 0, PAGE_SIZE); + paddr_t pdpt_frame = alloc_ppage (); + memset (get_vaddr_from_frame ((uint64_t)pdpt_frame / PAGE_SIZE), 0, PAGE_SIZE); pml4_base_ptr[1].present = 1; pml4_base_ptr[1].read_write = 1; From c3d59771926c84addd7f18c3c2b420616a4ba8f3 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:35:03 +0530 Subject: [PATCH 17/20] Add a message to signify that execution has completed --- src/kernel/entry.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel/entry.c b/src/kernel/entry.c index 4eecf71..91cce16 100644 --- a/src/kernel/entry.c +++ b/src/kernel/entry.c @@ -104,5 +104,6 @@ void _start (void) { printf ("CR3: %lx", cr3); // We're done, just hang... + printf ("\n\nAll execution completed."); hcf (); } \ No newline at end of file From eda50809fe1413e481b77824fddaf2cc94659739 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:37:41 +0530 Subject: [PATCH 18/20] Expose the alloc functions just in case --- include/kernel/memmgt.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/kernel/memmgt.h b/include/kernel/memmgt.h index 6046d07..68d4ec3 100644 --- a/include/kernel/memmgt.h +++ b/include/kernel/memmgt.h @@ -89,12 +89,15 @@ vaddr_t get_vaddr_t_from_ptr (void* ptr); void* get_vaddr_hhdm (uint64_t phys_address); void* vaddr_t_to_ptr (vaddr_t* virtual_addr); +void* alloc_vpages (size_t req_count); +void* alloc_vpage (void); +void free_vpages (void* ptr, size_t count); +void free_vpage (void* ptr); + void init_memmgt (uint64_t, struct limine_memmap_response*); void walk_pagetable (void); void* get_paddr (void* vaddr); -uint64_t allocate_physical_pageframes (size_t); - // LIBALLOC FUNCTION IMPLEMENTATIONS void* try_assign_pt (pt_entry_t*, size_t); From 77a9741241d18b7122520e73fa89cd5fcc5d6c56 Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:37:55 +0530 Subject: [PATCH 19/20] Make static some file-only functions --- src/kernel/memmgt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index bf857a4..cf80ec3 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -254,7 +254,7 @@ void page_fault_handler (registers_t* registers) { * @param b second vaddr * @return true if a lies before b, false otherwise */ -bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) { +static bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) { if (a->pml4_index == b->pml4_index) { if (a->pdpt_index == b->pdpt_index) { if (a->pd_index == b->pd_index) { @@ -275,7 +275,7 @@ bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) { * @param last last virtual address in range * @param base_addr base address of physical memory of corresponding size */ -void alloc_all_vpages_in_range (vaddr_t first, vaddr_t last, paddr_t base_addr) { +static void alloc_all_vpages_in_range (vaddr_t first, vaddr_t last, paddr_t base_addr) { uint64_t phys_base_track = (uint64_t)base_addr; pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; @@ -445,7 +445,7 @@ static bool is_table_empty (void* table_vaddr) { * @param first first virtual page in range * @param last last virtual page in range */ -void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { +static void free_all_vpages_in_range (vaddr_t first, vaddr_t last) { pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index]; if (!pml4t_entry->present) return; From f4ece744988602bd2698300b5dd3311b6a808e3f Mon Sep 17 00:00:00 2001 From: ryuukumar Date: Sun, 15 Mar 2026 15:38:36 +0530 Subject: [PATCH 20/20] init_memmgt -> __init_memmgt__ to match convention --- include/kernel/memmgt.h | 2 +- src/kernel/entry.c | 2 +- src/kernel/memmgt.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/kernel/memmgt.h b/include/kernel/memmgt.h index 68d4ec3..0566dc1 100644 --- a/include/kernel/memmgt.h +++ b/include/kernel/memmgt.h @@ -94,7 +94,7 @@ void* alloc_vpage (void); void free_vpages (void* ptr, size_t count); void free_vpage (void* ptr); -void init_memmgt (uint64_t, struct limine_memmap_response*); +void __init_memmgt__ (uint64_t, struct limine_memmap_response*); void walk_pagetable (void); void* get_paddr (void* vaddr); diff --git a/src/kernel/entry.c b/src/kernel/entry.c index 91cce16..2e45fed 100644 --- a/src/kernel/entry.c +++ b/src/kernel/entry.c @@ -72,7 +72,7 @@ void _start (void) { hcf (); } - init_memmgt (hhdm_base, memmap_req.response); + __init_memmgt__ (hhdm_base, memmap_req.response); set_color (0x44eeaa); diff --git a/src/kernel/memmgt.c b/src/kernel/memmgt.c index cf80ec3..0aa6a97 100644 --- a/src/kernel/memmgt.c +++ b/src/kernel/memmgt.c @@ -548,7 +548,7 @@ void free_vpage (void* ptr) { free_vpages (ptr, 1); } * Sets the base pointer for the PML4 table and stores the HHDM offset. * @param p_hhdm_offset The higher half direct mapping offset. */ -void init_memmgt (uint64_t p_hhdm_offset, struct limine_memmap_response* memmap_response) { +void __init_memmgt__ (uint64_t p_hhdm_offset, struct limine_memmap_response* memmap_response) { idt_register_handler (0xE, (irq_handler_t)page_fault_handler); memmap_response_ptr = memmap_response;