From 34e6f3c4f5c47b0b198d6422bd14703a53167c69 Mon Sep 17 00:00:00 2001 From: Dawid Pawliczek Date: Wed, 11 Mar 2026 07:59:40 +0100 Subject: [PATCH 1/4] Implement physical memory allocator using bitmap --- .../physical_memory/allocator.c | 145 +++++++++++++++--- .../physical_memory/allocator.h | 12 +- 2 files changed, 131 insertions(+), 26 deletions(-) diff --git a/src/kernel/memory_management/physical_memory/allocator.c b/src/kernel/memory_management/physical_memory/allocator.c index 0c8bc47c..5ba402d4 100644 --- a/src/kernel/memory_management/physical_memory/allocator.c +++ b/src/kernel/memory_management/physical_memory/allocator.c @@ -1,35 +1,140 @@ #include "allocator.h" - #include "memory_management/include/physical_memory/manager.h" #include "stdbigos/error.h" +#include "stdbigos/math.h" +#include "stdbigos/string.h" + +typedef struct { + uintptr_t area_base_addr; + size_t area_size; + u64 bitmap[]; +} pmallocator_header_t; + +typedef struct { + size_t first_bit; + size_t bit_count; +} bitmap_range_t; + + +static size_t calculate_header_size(memory_area_t area) { + const size_t bitmap_bits = area.size / phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); + const size_t bitmap_bytes = ALIGN_UP(bitmap_bits, 64) / 8; + const size_t total = sizeof(pmallocator_header_t) + bitmap_bytes; + return ALIGN_UP(total, 0x1000); +} + +static bitmap_range_t addr_range_to_bitmap_range(uintptr_t range_addr, size_t range_size, uintptr_t base_addr) { + + const size_t frame_size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); + const uintptr_t aligned_start = ALIGN_DOWN(range_addr, frame_size); + const uintptr_t aligned_end = ALIGN_UP(range_addr + range_size, frame_size); -error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 count, + bitmap_range_t result = { + .first_bit = (aligned_start - base_addr) / frame_size, + .bit_count = (aligned_end - aligned_start) / frame_size, + }; + return result; +} + +error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 reserved_areas_count, memory_area_t* headerOUT) { - (void)area; - (void)reserved_areas; - (void)count; - (void)headerOUT; - return ERR_NOT_IMPLEMENTED; + + const size_t header_size = calculate_header_size(area); + + for (uintptr_t i = area.addr; i + header_size <= area.addr + area.size; i += 0x1000) { + memory_area_t potential_header = { + .addr = i, + .size = header_size, + }; + bool overlaps_reserved = false; + for (u32 j = 0; j < reserved_areas_count; ++j) { + if (do_memory_areas_overlap(potential_header, reserved_areas[j])) { + overlaps_reserved = true; + break; + } + } + if (!overlaps_reserved) { + *headerOUT = potential_header; + return ERR_NONE; + } + } + + return ERR_NOT_ENOUGH_MEMORY; } error_t pmallocator_init_region(memory_area_t area, memory_region_t header, const memory_area_t* reserved_areas, - u32 count) { - (void)area; - (void)header; - (void)reserved_areas; - (void)count; - return ERR_NOT_IMPLEMENTED; + u32 reserved_areas_count) { + + const size_t header_size = calculate_header_size(area); + const size_t bitmap_size = header_size - sizeof(pmallocator_header_t); + pmallocator_header_t *effective_header = (pmallocator_header_t*)header.addr; + effective_header->area_base_addr = area.addr; + effective_header->area_size = area.size; + memset(effective_header->bitmap, 0, bitmap_size); + + for (u32 i = 0; i < reserved_areas_count; ++i) { + memory_area_t reserved_area = reserved_areas[i]; + bitmap_range_t bitmap_range = addr_range_to_bitmap_range(reserved_area.addr, reserved_area.size, area.addr); + + for (size_t j = bitmap_range.first_bit; j < bitmap_range.first_bit + bitmap_range.bit_count; ++j) { + effective_header->bitmap[j / 64] |= (1ULL << (j % 64)); + } + } + + bitmap_range_t bitmap_range = addr_range_to_bitmap_range((uintptr_t)header.addr, header.size, area.addr); + for (size_t j = bitmap_range.first_bit; j < bitmap_range.first_bit + bitmap_range.bit_count; ++j) { + effective_header->bitmap[j / 64] |= (1ULL << (j % 64)); + } + + return ERR_NONE; } error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t* addrOUT) { - (void)frame_order; - *addrOUT = *addrOUT; - (void)header; - return ERR_NOT_IMPLEMENTED; + + const size_t frame_size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); + const size_t frame_count = 1ULL << frame_order; + pmallocator_header_t *effective_header = (pmallocator_header_t*)header.addr; + + const size_t bitmap_bits = effective_header->area_size / frame_size; + + for (size_t i = 0; i + frame_count <= bitmap_bits; i += frame_count) { + + bool all_free = true; + + for (size_t j = i; j < i + frame_count; ++j) { + if (effective_header->bitmap[j / 64] & (1ULL << (j % 64)) ) { + all_free = false; + break; + } + } + + if (all_free) { + for (size_t j = i; j < i + frame_count; ++j) { + effective_header->bitmap[j / 64] |= (1ULL << (j % 64)); + } + *addrOUT = (phys_addr_t)(effective_header->area_base_addr + (i * frame_size)); + return ERR_NONE; + } + } + + return ERR_NOT_ENOUGH_MEMORY; } error_t pmallocator_free(phys_addr_t addr, memory_region_t header) { - (void)addr; - (void)header; - return ERR_NOT_IMPLEMENTED; + + const size_t frame_size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); + pmallocator_header_t *effective_header = (pmallocator_header_t*)header.addr; + const uintptr_t phys_addr = (uintptr_t)addr; + const size_t addr_bit = ( phys_addr - effective_header->area_base_addr) / frame_size; + + if (phys_addr < effective_header->area_base_addr || addr_bit >= effective_header->area_size / frame_size) { + return ERR_OUT_OF_BOUNDS; + } + + if (!(effective_header->bitmap[addr_bit / 64] & (1ULL << (addr_bit % 64))) ) { + return ERR_NOT_VALID; + } + + effective_header->bitmap[addr_bit / 64] &= ~(1ULL << (addr_bit % 64)); + return ERR_NONE; } diff --git a/src/kernel/memory_management/physical_memory/allocator.h b/src/kernel/memory_management/physical_memory/allocator.h index 2baebf50..0058cc4a 100644 --- a/src/kernel/memory_management/physical_memory/allocator.h +++ b/src/kernel/memory_management/physical_memory/allocator.h @@ -17,13 +17,13 @@ * * @param area The phiscal memory area to allocate from. Will be aligned to at least 4KiB boundry * @param reserved_areas An array of reserved areas from which allocations are not allowed - * @param count The count of reserved areas + * @param reserved_areas_count The count of reserved areas * * @retval ERR_NONE Success - * @retval ERR_BAD_ARG if @p reserved_areas is null and @p count is non zero or vice versa. + * @retval ERR_BAD_ARG if @p reserved_areas is null and @p reserved_areas_count is non zero or vice versa. * */ [[gnu::nonnull(4)]] -error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 count, +error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 reserved_areas_count, memory_area_t* headerOUT); /** @@ -33,10 +33,10 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved * @param area The phiscal memory area to allocate from. Will be aligned to at least 4KiB boundry * @param header A memory region of size at least `pmallocator_get_header_size(@p area)` aligned to 4KiB boundry * @param reserved_areas An array of reserved areas from which allocations are not allowed - * @param count The count of reserved areas + * @param reserved_areas_count The count of reserved areas * * @retval ERR_NONE Success - * @retval ERR_BAD_ARG if @p reserved_areas is null and @p count is non zero or vice versa. + * @retval ERR_BAD_ARG if @p reserved_areas is null and @p reserved_areas_count is non zero or vice versa. * * @note The header region overlaps with area, it must be marked and not be allocated from. * area. @@ -44,7 +44,7 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved * after the change, no pointers can be stored inside the `header` region. * */ error_t pmallocator_init_region(memory_area_t area, memory_region_t header, const memory_area_t* reserved_areas, - u32 count); + u32 reserved_areas_count); /** * @ingroup kmm From 773a14968e1daf146e0013cc3a9e5e5364688fdb Mon Sep 17 00:00:00 2001 From: Dawid Pawliczek Date: Fri, 13 Mar 2026 14:11:11 +0100 Subject: [PATCH 2/4] Refactor --- .../include/physical_memory/manager.h | 32 ++++--- .../physical_memory/allocator.c | 94 +++++++++++-------- .../physical_memory/allocator.h | 31 +++--- .../physical_memory/manager.c | 18 ++-- 4 files changed, 97 insertions(+), 78 deletions(-) diff --git a/src/kernel/memory_management/include/physical_memory/manager.h b/src/kernel/memory_management/include/physical_memory/manager.h index d50f89d0..c75537cf 100644 --- a/src/kernel/memory_management/include/physical_memory/manager.h +++ b/src/kernel/memory_management/include/physical_memory/manager.h @@ -54,22 +54,24 @@ static inline memory_region_t phys_mem_reg_to_reg(physical_memory_region_t pmr) /// @ingroup kmm /// @ingroup kmm_manager typedef enum : u8 { - FRAME_SIZE_4KiB = 0, - FRAME_SIZE_8KiB = 1, - FRAME_SIZE_16KiB = 2, - FRAME_SIZE_32KiB = 3, - FRAME_SIZE_64KiB = 4, - FRAME_SIZE_128KiB = 5, - FRAME_SIZE_256KiB = 6, - FRAME_SIZE_512KiB = 7, - FRAME_SIZE_1MiB = 8, - FRAME_SIZE_2MiB = 9, - FRAME_SIZE_1GiB = 18, -} frame_size_t; // NOTE: value of frame_size_t is (4KiB << frame_size) + FRAME_ORDER_4KiB = 0, + FRAME_ORDER_8KiB = 1, + FRAME_ORDER_16KiB = 2, + FRAME_ORDER_32KiB = 3, + FRAME_ORDER_64KiB = 4, + FRAME_ORDER_128KiB = 5, + FRAME_ORDER_256KiB = 6, + FRAME_ORDER_512KiB = 7, + FRAME_ORDER_1MiB = 8, + FRAME_ORDER_2MiB = 9, + FRAME_ORDER_1GiB = 18, +} frame_order_t; // NOTE: value is the order of 4KiB frames (frame count = 1 << order) + +#define PAGE_SIZE 0x1000UL /// @ingroup kmm /// @ingroup kmm_manager -u64 phys_mem_get_frame_size_in_bytes(frame_size_t fs); +u64 phys_mem_get_frame_size_in_bytes(frame_order_t fs); /** * @ingroup kmm @@ -97,7 +99,7 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co * @retval ERR_OUT_OF_MEMORY The block of specified size was not able to be allocated * */ [[gnu::nonnull]] -error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT); +error_t phys_mem_alloc_frame(frame_order_t frame_size, phys_addr_t* addrOUT); /** * @ingroup kmm @@ -105,6 +107,6 @@ error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT); * @retval ERR_NONE * @retval ERR_NOT_VALID The address being freed was reported as not allocated * */ -error_t phys_mem_free_frame(phys_addr_t addr); +error_t phys_mem_free_frame(frame_order_t frame_size, phys_addr_t addr); #endif //! BIGOS_KERNEL_MEMORY_MANAGMENT_PHYSICAL_MEMORY_MANAGMENT diff --git a/src/kernel/memory_management/physical_memory/allocator.c b/src/kernel/memory_management/physical_memory/allocator.c index 5ba402d4..1f1c3541 100644 --- a/src/kernel/memory_management/physical_memory/allocator.c +++ b/src/kernel/memory_management/physical_memory/allocator.c @@ -16,32 +16,49 @@ typedef struct { } bitmap_range_t; +static void bitmap_set(u64* bitmap, size_t bit) { + bitmap[bit / 64] |= (1ULL << (bit % 64)); +} + +static void bitmap_clear(u64* bitmap, size_t bit) { + bitmap[bit / 64] &= ~(1ULL << (bit % 64)); +} + +static bool bitmap_test(const u64* bitmap, size_t bit) { + return bitmap[bit / 64] & (1ULL << (bit % 64)); +} + +static void bitmap_set_range(u64* bitmap, size_t start, size_t count) { + for (size_t j = start; j < start + count; ++j) + bitmap_set(bitmap, j); +} + static size_t calculate_header_size(memory_area_t area) { - const size_t bitmap_bits = area.size / phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); + const size_t bitmap_bits = area.size / PAGE_SIZE; const size_t bitmap_bytes = ALIGN_UP(bitmap_bits, 64) / 8; const size_t total = sizeof(pmallocator_header_t) + bitmap_bytes; - return ALIGN_UP(total, 0x1000); + return ALIGN_UP(total, PAGE_SIZE); } static bitmap_range_t addr_range_to_bitmap_range(uintptr_t range_addr, size_t range_size, uintptr_t base_addr) { - const size_t frame_size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); - const uintptr_t aligned_start = ALIGN_DOWN(range_addr, frame_size); - const uintptr_t aligned_end = ALIGN_UP(range_addr + range_size, frame_size); + const uintptr_t aligned_start = ALIGN_DOWN(range_addr, PAGE_SIZE); + const uintptr_t aligned_end = ALIGN_UP(range_addr + range_size, PAGE_SIZE); bitmap_range_t result = { - .first_bit = (aligned_start - base_addr) / frame_size, - .bit_count = (aligned_end - aligned_start) / frame_size, + .first_bit = (aligned_start - base_addr) / PAGE_SIZE, + .bit_count = (aligned_end - aligned_start) / PAGE_SIZE, }; return result; } + error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 reserved_areas_count, memory_area_t* headerOUT) { const size_t header_size = calculate_header_size(area); - for (uintptr_t i = area.addr; i + header_size <= area.addr + area.size; i += 0x1000) { + for (uintptr_t i = area.addr; i + header_size <= area.addr + area.size; i += PAGE_SIZE) { memory_area_t potential_header = { .addr = i, .size = header_size, @@ -62,57 +79,52 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved return ERR_NOT_ENOUGH_MEMORY; } -error_t pmallocator_init_region(memory_area_t area, memory_region_t header, const memory_area_t* reserved_areas, +error_t pmallocator_init_region(memory_area_t area, memory_region_t header_region, const memory_area_t* reserved_areas, u32 reserved_areas_count) { + pmallocator_header_t *header = header_region.addr; + header->area_size = area.size; + header->area_base_addr = area.addr; + const size_t header_size = calculate_header_size(area); const size_t bitmap_size = header_size - sizeof(pmallocator_header_t); - pmallocator_header_t *effective_header = (pmallocator_header_t*)header.addr; - effective_header->area_base_addr = area.addr; - effective_header->area_size = area.size; - memset(effective_header->bitmap, 0, bitmap_size); + + memset(header->bitmap, 0, bitmap_size); for (u32 i = 0; i < reserved_areas_count; ++i) { memory_area_t reserved_area = reserved_areas[i]; bitmap_range_t bitmap_range = addr_range_to_bitmap_range(reserved_area.addr, reserved_area.size, area.addr); - for (size_t j = bitmap_range.first_bit; j < bitmap_range.first_bit + bitmap_range.bit_count; ++j) { - effective_header->bitmap[j / 64] |= (1ULL << (j % 64)); - } + bitmap_set_range(header->bitmap, bitmap_range.first_bit, bitmap_range.bit_count); } - bitmap_range_t bitmap_range = addr_range_to_bitmap_range((uintptr_t)header.addr, header.size, area.addr); - for (size_t j = bitmap_range.first_bit; j < bitmap_range.first_bit + bitmap_range.bit_count; ++j) { - effective_header->bitmap[j / 64] |= (1ULL << (j % 64)); - } + bitmap_range_t bitmap_range = addr_range_to_bitmap_range((uintptr_t)header_region.addr, header_region.size, area.addr); + bitmap_set_range(header->bitmap, bitmap_range.first_bit, bitmap_range.bit_count); return ERR_NONE; } -error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t* addrOUT) { +error_t pmallocator_allocate(frame_order_t frame_order, memory_region_t header_region, phys_addr_t* addrOUT) { - const size_t frame_size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); - const size_t frame_count = 1ULL << frame_order; - pmallocator_header_t *effective_header = (pmallocator_header_t*)header.addr; + pmallocator_header_t *header = header_region.addr; - const size_t bitmap_bits = effective_header->area_size / frame_size; + const size_t bitmap_bits = header->area_size / PAGE_SIZE; + const size_t frame_count = 1ULL << frame_order; for (size_t i = 0; i + frame_count <= bitmap_bits; i += frame_count) { bool all_free = true; for (size_t j = i; j < i + frame_count; ++j) { - if (effective_header->bitmap[j / 64] & (1ULL << (j % 64)) ) { + if (bitmap_test(header->bitmap, j)) { all_free = false; break; } } if (all_free) { - for (size_t j = i; j < i + frame_count; ++j) { - effective_header->bitmap[j / 64] |= (1ULL << (j % 64)); - } - *addrOUT = (phys_addr_t)(effective_header->area_base_addr + (i * frame_size)); + bitmap_set_range(header->bitmap, i, frame_count); + *addrOUT = (phys_addr_t)(header->area_base_addr + (i * PAGE_SIZE)); return ERR_NONE; } } @@ -120,21 +132,25 @@ error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t return ERR_NOT_ENOUGH_MEMORY; } -error_t pmallocator_free(phys_addr_t addr, memory_region_t header) { +error_t pmallocator_free(frame_order_t frame_order, phys_addr_t addr, memory_region_t header_region) { + + pmallocator_header_t *header = header_region.addr; - const size_t frame_size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB); - pmallocator_header_t *effective_header = (pmallocator_header_t*)header.addr; + const size_t frame_count = 1ULL << frame_order; const uintptr_t phys_addr = (uintptr_t)addr; - const size_t addr_bit = ( phys_addr - effective_header->area_base_addr) / frame_size; + const size_t addr_bit = (phys_addr - header->area_base_addr) / PAGE_SIZE; + const size_t total_pages = header->area_size / PAGE_SIZE; - if (phys_addr < effective_header->area_base_addr || addr_bit >= effective_header->area_size / frame_size) { + if (phys_addr < header->area_base_addr || addr_bit + frame_count > total_pages) return ERR_OUT_OF_BOUNDS; - } - if (!(effective_header->bitmap[addr_bit / 64] & (1ULL << (addr_bit % 64))) ) { - return ERR_NOT_VALID; + for (size_t j = addr_bit; j < addr_bit + frame_count; ++j) { + if (!bitmap_test(header->bitmap, j)) + return ERR_NOT_VALID; } - effective_header->bitmap[addr_bit / 64] &= ~(1ULL << (addr_bit % 64)); + for (size_t j = addr_bit; j < addr_bit + frame_count; ++j) + bitmap_clear(header->bitmap, j); + return ERR_NONE; } diff --git a/src/kernel/memory_management/physical_memory/allocator.h b/src/kernel/memory_management/physical_memory/allocator.h index 0058cc4a..8e5e50a8 100644 --- a/src/kernel/memory_management/physical_memory/allocator.h +++ b/src/kernel/memory_management/physical_memory/allocator.h @@ -12,10 +12,10 @@ * @ingroup kmm * @ingroup phys_allocator * - * @brief Looks for an area of suitable size and alignmnet to store all metadata about the @p area that the allocator + * @brief Looks for an area of suitable size and alignment to store all metadata about the @p area that the allocator * needs * - * @param area The phiscal memory area to allocate from. Will be aligned to at least 4KiB boundry + * @param area The physical memory area to allocate from. Will be aligned to at least 4KiB boundary * @param reserved_areas An array of reserved areas from which allocations are not allowed * @param reserved_areas_count The count of reserved areas * @@ -30,8 +30,8 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved * @ingroup kmm * @ingroup phys_allocator * - * @param area The phiscal memory area to allocate from. Will be aligned to at least 4KiB boundry - * @param header A memory region of size at least `pmallocator_get_header_size(@p area)` aligned to 4KiB boundry + * @param area The physical memory area to allocate from. Will be aligned to at least 4KiB boundary + * @param header_region A memory region of size at least `pmallocator_get_header_size(@p area)` aligned to 4KiB boundary * @param reserved_areas An array of reserved areas from which allocations are not allowed * @param reserved_areas_count The count of reserved areas * @@ -43,38 +43,39 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved * @note All pointers will break upon change of address space, because this is initialized before and will be used * after the change, no pointers can be stored inside the `header` region. * */ -error_t pmallocator_init_region(memory_area_t area, memory_region_t header, const memory_area_t* reserved_areas, +error_t pmallocator_init_region(memory_area_t area, memory_region_t header_region, const memory_area_t* reserved_areas, u32 reserved_areas_count); /** * @ingroup kmm * @ingroup phys_allocator * - * @param frame_order The frame size gives as `(1 << frame_order)` - * @param addrOUT Pointer the the variable to which the return address will be written to. - * The return address will be aligned to the frame size - * @param header + * @param frame_order The number of 4KiB frames to allocate is `(1 << frame_order)` + * @param header_region + * @param addrOUT Pointer to the variable to which the return address will be written to. + * The return address will be aligned to the allocation size * * @retval ERR_NONE Success - * @retval ERR_NOT_VALID The requested frame size is not supported by the allocator - * @retval ERR_PHYSICAL_MEMORY_FULL Not enough memory in the area represented by @p header to allocate a frame of + * @retval ERR_NOT_VALID The requested frame order is not supported by the allocator + * @retval ERR_NOT_ENOUGH_MEMORY Not enough memory in the area represented by @p header_region to allocate a frame of * desired size * - * @note 4KiB frame (or @p frame_order = 12) must be a valid frame size. + * @note FRAME_ORDER_4KiB (order 0) must be a valid frame order. * */ [[gnu::nonnull]] -error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t* addrOUT); +error_t pmallocator_allocate(frame_order_t frame_order, memory_region_t header_region, phys_addr_t* addrOUT); /** * @ingroup kmm * @ingroup phys_allocator * + * @param frame_order * @param addr - * @param header + * @param header_region * * @retval ERR_NONE Success * @retval ERR_NOT_VALID The area represented by @p addr is already free. * */ -error_t pmallocator_free(phys_addr_t addr, memory_region_t header); +error_t pmallocator_free(frame_order_t frame_order, phys_addr_t addr, memory_region_t header_region); #endif diff --git a/src/kernel/memory_management/physical_memory/manager.c b/src/kernel/memory_management/physical_memory/manager.c index af99855e..8ca8037e 100644 --- a/src/kernel/memory_management/physical_memory/manager.c +++ b/src/kernel/memory_management/physical_memory/manager.c @@ -52,9 +52,9 @@ static error_t store_header(physical_memory_region_t header) { } else { physical_memory_region_t new_reg = { .addr = nullptr, - .size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB), + .size = PAGE_SIZE, }; - error_t err = phys_mem_alloc_frame(FRAME_SIZE_4KiB, &new_reg.addr); + error_t err = phys_mem_alloc_frame(FRAME_ORDER_4KiB, &new_reg.addr); if (err) return err; err = init_header_storage_node(new_reg); @@ -73,7 +73,7 @@ static error_t store_header(physical_memory_region_t header) { // Public // ========================================== -u64 phys_mem_get_frame_size_in_bytes(frame_size_t fs) { +u64 phys_mem_get_frame_size_in_bytes(frame_order_t fs) { const u64 size_4KiB = 0x1000; return (size_4KiB << fs); } @@ -113,10 +113,10 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co } if (g_root_header_storage_node == nullptr) { physical_memory_region_t new_reg = { - .size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB), + .size = PAGE_SIZE, .addr = nullptr, }; - err = pmallocator_allocate(12, header_region, &new_reg.addr); + err = pmallocator_allocate(FRAME_ORDER_4KiB, header_region, &new_reg.addr); // NOTE: Since we failed to allocate the smallest possible frame size, we assume that this region is // useless. if (err) { @@ -149,13 +149,13 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co } // NOLINTEND readability-function-cognitive-complexity -error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT) { +error_t phys_mem_alloc_frame(frame_order_t frame_size, phys_addr_t* addrOUT) { u32 idx = 0; physical_memory_region_t header_pmr; while (get_header_pmr(idx, &header_pmr) == ERR_NONE) { memory_region_t header_region = phys_mem_reg_to_reg(header_pmr); phys_addr_t frame_data = nullptr; - error_t err = pmallocator_allocate(frame_size + 12, header_region, &frame_data); + error_t err = pmallocator_allocate(frame_size, header_region, &frame_data); if (err) { ++idx; continue; @@ -169,12 +169,12 @@ error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT) { return ERR_OUT_OF_MEMORY; } -error_t phys_mem_free_frame(phys_addr_t addr) { +error_t phys_mem_free_frame(frame_order_t frame_size, phys_addr_t addr) { u32 idx = 0; physical_memory_region_t header_pmr; while (get_header_pmr(idx, &header_pmr) == ERR_NONE) { memory_region_t header_region = phys_mem_reg_to_reg(header_pmr); - error_t err = pmallocator_free(addr, header_region); + error_t err = pmallocator_free(frame_size, addr, header_region); if (err) { ++idx; continue; From 5077507c47f13d708fbd6e416db6dc73826bdf67 Mon Sep 17 00:00:00 2001 From: Dawid Pawliczek Date: Fri, 13 Mar 2026 14:22:26 +0100 Subject: [PATCH 3/4] update phys_mem_get_frame_size_in_bytes parameter type to frame_order_t --- src/kernel/memory_management/include/physical_memory/manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/memory_management/include/physical_memory/manager.h b/src/kernel/memory_management/include/physical_memory/manager.h index ac9f2c01..7ef7abac 100644 --- a/src/kernel/memory_management/include/physical_memory/manager.h +++ b/src/kernel/memory_management/include/physical_memory/manager.h @@ -71,7 +71,7 @@ typedef enum : u8 { /// @ingroup kmm /// @ingroup pmm -u64 phys_mem_get_frame_size_in_bytes(frame_size_t fs); +u64 phys_mem_get_frame_size_in_bytes(frame_order_t fs); /** * @ingroup kmm From a82fe6271db11c515478e7904e837fdbd3fb2393 Mon Sep 17 00:00:00 2001 From: Dawid Pawliczek Date: Fri, 13 Mar 2026 14:28:23 +0100 Subject: [PATCH 4/4] Fix format --- .../physical_memory/allocator.c | 26 ++++++++----------- .../physical_memory/allocator.h | 3 ++- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/kernel/memory_management/physical_memory/allocator.c b/src/kernel/memory_management/physical_memory/allocator.c index 1f1c3541..3ffec2e7 100644 --- a/src/kernel/memory_management/physical_memory/allocator.c +++ b/src/kernel/memory_management/physical_memory/allocator.c @@ -1,4 +1,5 @@ #include "allocator.h" + #include "memory_management/include/physical_memory/manager.h" #include "stdbigos/error.h" #include "stdbigos/math.h" @@ -15,7 +16,6 @@ typedef struct { size_t bit_count; } bitmap_range_t; - static void bitmap_set(u64* bitmap, size_t bit) { bitmap[bit / 64] |= (1ULL << (bit % 64)); } @@ -29,8 +29,9 @@ static bool bitmap_test(const u64* bitmap, size_t bit) { } static void bitmap_set_range(u64* bitmap, size_t start, size_t count) { - for (size_t j = start; j < start + count; ++j) + for (size_t j = start; j < start + count; ++j) { bitmap_set(bitmap, j); + } } static size_t calculate_header_size(memory_area_t area) { @@ -41,9 +42,8 @@ static size_t calculate_header_size(memory_area_t area) { } static bitmap_range_t addr_range_to_bitmap_range(uintptr_t range_addr, size_t range_size, uintptr_t base_addr) { - const uintptr_t aligned_start = ALIGN_DOWN(range_addr, PAGE_SIZE); - const uintptr_t aligned_end = ALIGN_UP(range_addr + range_size, PAGE_SIZE); + const uintptr_t aligned_end = ALIGN_UP(range_addr + range_size, PAGE_SIZE); bitmap_range_t result = { .first_bit = (aligned_start - base_addr) / PAGE_SIZE, @@ -52,10 +52,8 @@ static bitmap_range_t addr_range_to_bitmap_range(uintptr_t range_addr, size_t ra return result; } - error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 reserved_areas_count, memory_area_t* headerOUT) { - const size_t header_size = calculate_header_size(area); for (uintptr_t i = area.addr; i + header_size <= area.addr + area.size; i += PAGE_SIZE) { @@ -81,8 +79,7 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved error_t pmallocator_init_region(memory_area_t area, memory_region_t header_region, const memory_area_t* reserved_areas, u32 reserved_areas_count) { - - pmallocator_header_t *header = header_region.addr; + pmallocator_header_t* header = header_region.addr; header->area_size = area.size; header->area_base_addr = area.addr; @@ -98,21 +95,20 @@ error_t pmallocator_init_region(memory_area_t area, memory_region_t header_regio bitmap_set_range(header->bitmap, bitmap_range.first_bit, bitmap_range.bit_count); } - bitmap_range_t bitmap_range = addr_range_to_bitmap_range((uintptr_t)header_region.addr, header_region.size, area.addr); + bitmap_range_t bitmap_range = + addr_range_to_bitmap_range((uintptr_t)header_region.addr, header_region.size, area.addr); bitmap_set_range(header->bitmap, bitmap_range.first_bit, bitmap_range.bit_count); return ERR_NONE; } error_t pmallocator_allocate(frame_order_t frame_order, memory_region_t header_region, phys_addr_t* addrOUT) { - - pmallocator_header_t *header = header_region.addr; + pmallocator_header_t* header = header_region.addr; const size_t bitmap_bits = header->area_size / PAGE_SIZE; const size_t frame_count = 1ULL << frame_order; for (size_t i = 0; i + frame_count <= bitmap_bits; i += frame_count) { - bool all_free = true; for (size_t j = i; j < i + frame_count; ++j) { @@ -133,8 +129,7 @@ error_t pmallocator_allocate(frame_order_t frame_order, memory_region_t header_r } error_t pmallocator_free(frame_order_t frame_order, phys_addr_t addr, memory_region_t header_region) { - - pmallocator_header_t *header = header_region.addr; + pmallocator_header_t* header = header_region.addr; const size_t frame_count = 1ULL << frame_order; const uintptr_t phys_addr = (uintptr_t)addr; @@ -149,8 +144,9 @@ error_t pmallocator_free(frame_order_t frame_order, phys_addr_t addr, memory_reg return ERR_NOT_VALID; } - for (size_t j = addr_bit; j < addr_bit + frame_count; ++j) + for (size_t j = addr_bit; j < addr_bit + frame_count; ++j) { bitmap_clear(header->bitmap, j); + } return ERR_NONE; } diff --git a/src/kernel/memory_management/physical_memory/allocator.h b/src/kernel/memory_management/physical_memory/allocator.h index 9b3c87c4..04f3f0a0 100644 --- a/src/kernel/memory_management/physical_memory/allocator.h +++ b/src/kernel/memory_management/physical_memory/allocator.h @@ -31,7 +31,8 @@ error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved * @ingroup palloc * * @param area The physical memory area to allocate from. Will be aligned to at least 4KiB boundary - * @param header_region A memory region of size at least `pmallocator_get_header_size(@p area)` aligned to 4KiB boundary + * @param header_region A memory region of size at least `pmallocator_get_header_size(@p area)` aligned to 4KiB + * boundary * @param reserved_areas An array of reserved areas from which allocations are not allowed * @param reserved_areas_count The count of reserved areas *