From be32189323ba8c46091d6deaf091cf41147426b4 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Wed, 7 May 2025 14:06:25 +0000 Subject: wip custom heap allocation functions for user mode --- .../arch/memory/heap/global_heap_allocator.hpp | 39 +++++++++++++--- .../include/arch/memory/heap/heap_allocator.hpp | 6 ++- .../src/memory/heap/global_heap_allocator.cpp | 54 +++++++++++++++------- arch/x86_64/src/memory/main.cpp | 6 +-- arch/x86_64/src/user/main.cpp | 26 ++++++----- 5 files changed, 92 insertions(+), 39 deletions(-) diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index 772f171..bfc7b67 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -45,7 +45,7 @@ namespace teachos::arch::memory::heap * @param size Amount of bytes that should be allocated * @return void* Pointer to the start of the allocatable memory area */ - static auto allocate(std::size_t size) -> void *; + static auto kmalloc(std::size_t size) -> void *; /** * @brief Deallocated all memory associated with the memory area starting from the given pointer address. @@ -53,17 +53,44 @@ namespace teachos::arch::memory::heap * * @param pointer Previously allocated memory area, that should now be freed */ - static auto deallocate(void * pointer) noexcept -> void; + static auto kfree(void * pointer) noexcept -> void; + + /** + * @brief Allocates the given amount of memory and returns the pointer to the start of the allocatable memory area. + * Simply forwards the call to the allocate method of the registered heap_allocation implementation + * + * @param size Amount of bytes that should be allocated + * @return void* Pointer to the start of the allocatable memory area + */ + [[gnu::section(".user_text")]] + static auto malloc(std::size_t size) -> void *; + + /** + * @brief Deallocated all memory associated with the memory area starting from the given pointer address. + * Simply forwards the call to the deallocate method of the registered heap_allocation implementation + * + * @param pointer Previously allocated memory area, that should now be freed + */ + [[gnu::section(".user_text")]] + static auto free(void * pointer) noexcept -> void; private: - static heap_allocator * allocator_instance; ///< Instance used to actually allocate and deallocate + static heap_allocator * kernel_allocator_instance; ///< Instance used to allocate and deallocate kernel heap memory + static heap_allocator * user_allocator_instance; ///< Instance used to allocate and deallocate user heap memory + + /** + * @brief Either returns the previously registered heap allocated or halts further execution + * + * @return Reference to the registered kernel heap allocation + */ + static auto kernel() -> heap_allocator &; /** - * @brief Either returns the previously registered heap allocated or halts furthere execution + * @brief Either returns the previously registered heap allocated or halts further execution * - * @return Reference to the registered heap allocation + * @return Reference to the registered user heap allocation */ - static auto get() -> heap_allocator &; + static auto user() -> heap_allocator &; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp index 6aed3d8..420a1d3 100644 --- a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -5,8 +5,10 @@ namespace teachos::arch::memory::heap { - std::size_t constexpr HEAP_START = 0x100000000; - std::size_t constexpr HEAP_SIZE = 100 * 1024; + std::size_t constexpr KERNEL_HEAP_START = 0x100000000; + std::size_t constexpr KERNEL_HEAP_SIZE = 100 * 1024; + std::size_t constexpr USER_HEAP_START = 0x100019000; // Starts directly after kernel heap + std::size_t constexpr USER_HEAP_SIZE = 100 * 1024; /** * @brief Heap allocator interface containing methods required to allocate and deallocate heap memory areas diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index c1ca160..51f6261 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -6,15 +6,20 @@ namespace teachos::arch::memory::heap { - heap_allocator * global_heap_allocator::allocator_instance = nullptr; + heap_allocator * global_heap_allocator::kernel_allocator_instance = nullptr; + heap_allocator * global_heap_allocator::user_allocator_instance = nullptr; - auto global_heap_allocator::allocate(std::size_t size) -> void * { return get().allocate(size); } + auto global_heap_allocator::kmalloc(std::size_t size) -> void * { return kernel().allocate(size); } - auto global_heap_allocator::deallocate(void * pointer) noexcept -> void { get().deallocate(pointer); } + auto global_heap_allocator::kfree(void * pointer) noexcept -> void { kernel().deallocate(pointer); } + + auto global_heap_allocator::malloc(std::size_t size) -> void * { return user().allocate(size); } + + auto global_heap_allocator::free(void * pointer) noexcept -> void { user().deallocate(pointer); } auto global_heap_allocator::register_heap_allocator(heap_allocator_type new_type) -> void { - exception_handling::assert(allocator_instance == nullptr, + exception_handling::assert(kernel_allocator_instance == nullptr, "Calling register_heap_allocator_type can only be done once."); switch (new_type) @@ -23,56 +28,71 @@ namespace teachos::arch::memory::heap // Nothing to do break; case heap_allocator_type::BUMP: { - static bump_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - allocator_instance = &allocator; + static bump_allocator kernel_allocator{KERNEL_HEAP_START, KERNEL_HEAP_START + KERNEL_HEAP_SIZE}; + kernel_allocator_instance = &kernel_allocator; + + static bump_allocator user_allocator{USER_HEAP_START, USER_HEAP_START + USER_HEAP_SIZE}; + user_allocator_instance = &user_allocator; break; } case heap_allocator_type::LINKED_LIST: { - static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - allocator_instance = &allocator; + static linked_list_allocator kernel_allocator{KERNEL_HEAP_START, KERNEL_HEAP_START + KERNEL_HEAP_SIZE}; + kernel_allocator_instance = &kernel_allocator; + + static linked_list_allocator user_allocator{USER_HEAP_START, USER_HEAP_START + USER_HEAP_SIZE}; + user_allocator_instance = &user_allocator; break; } } } - auto global_heap_allocator::get() -> heap_allocator & + auto global_heap_allocator::kernel() -> heap_allocator & + { + exception_handling::assert(kernel_allocator_instance != nullptr, + "Attempted to allocate or deallocate using the global_heap_allocator before " + "register_heap_allocation_type was called."); + + return *kernel_allocator_instance; + } + + auto global_heap_allocator::user() -> heap_allocator & { - exception_handling::assert(allocator_instance != nullptr, + exception_handling::assert(user_allocator_instance != nullptr, "Attempted to allocate or deallocate using the global_heap_allocator before " "register_heap_allocation_type was called."); - return *allocator_instance; + return *user_allocator_instance; } } // namespace teachos::arch::memory::heap auto operator new(std::size_t size) -> void * { - return teachos::arch::memory::heap::global_heap_allocator::allocate(size); + return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); } auto operator delete(void * pointer) noexcept -> void { - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); + teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); } auto operator delete(void * pointer, std::size_t size) noexcept -> void { (void)size; - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); + teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); } auto operator new[](std::size_t size) -> void * { - return teachos::arch::memory::heap::global_heap_allocator::allocate(size); + return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); } auto operator delete[](void * pointer) noexcept -> void { - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); + teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); } auto operator delete[](void * pointer, std::size_t size) noexcept -> void { (void)size; - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); + teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); } diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp index bd094e0..558fbce 100644 --- a/arch/x86_64/src/memory/main.cpp +++ b/arch/x86_64/src/memory/main.cpp @@ -5,7 +5,7 @@ #include "arch/kernel/cpu/msr.hpp" #include "arch/memory/allocator/area_frame_allocator.hpp" #include "arch/memory/allocator/concept.hpp" -#include "arch/memory/heap/heap_allocator.hpp" +#include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/paging/active_page_table.hpp" #include "arch/memory/paging/kernel_mapper.hpp" @@ -22,9 +22,9 @@ namespace teachos::arch::memory template auto remap_heap(T & allocator, paging::active_page_table & active_table) -> void { - auto const start_page = paging::virtual_page::containing_address(memory::heap::HEAP_START); + auto const start_page = paging::virtual_page::containing_address(heap::KERNEL_HEAP_START); auto const end_page = - ++(paging::virtual_page::containing_address(memory::heap::HEAP_START + memory::heap::HEAP_SIZE - 1)); + ++(paging::virtual_page::containing_address(heap::KERNEL_HEAP_START + heap::KERNEL_HEAP_SIZE - 1)); paging::page_container::iterator const begin{start_page}; paging::page_container::iterator const end{end_page}; paging::page_container const pages{begin, end}; diff --git a/arch/x86_64/src/user/main.cpp b/arch/x86_64/src/user/main.cpp index 3e7b0ec..4f6e688 100644 --- a/arch/x86_64/src/user/main.cpp +++ b/arch/x86_64/src/user/main.cpp @@ -1,8 +1,9 @@ #include "arch/user/main.hpp" #include "arch/context_switching/syscall/main.hpp" +#include "arch/memory/heap/global_heap_allocator.hpp" -// TODO: Disallow this import +// TODO: Disallow these imports #include "arch/kernel/cpu/if.hpp" #include "arch/video/vga/text.hpp" @@ -11,20 +12,23 @@ namespace teachos::arch::user auto main() -> void { char constexpr syscall_message[] = "Successfully entered user mode and wrote to VGA buffer via syscall!"; - auto const error = context_switching::syscall::syscall(context_switching::syscall::type::WRITE, - {reinterpret_cast(&syscall_message)}); + context_switching::syscall::syscall(context_switching::syscall::type::WRITE, + {reinterpret_cast(&syscall_message)}); - kernel::cpu::clear_interrupt_flag(); // Causes crash Kernel Code (.text) is not mapped in User mMde + // kernel::cpu::clear_interrupt_flag(); // Causes crash Kernel Code (.text) is not mapped in User mMde - auto test = new int{20}; // Causes crash Heap is not mapped in User Mode + auto test = memory::heap::global_heap_allocator::malloc(20U); (void)test; - if (!error) - { - // Causes crash vga is not mapped in User Mode - video::vga::text::write("Successfully made a SYSCALL and returned with SYSRETQ!", - video::vga::text::common_attributes::green_on_black); - } + // auto test = new int{20}; // Causes crash Heap is not mapped in User Mode + // (void)test; + + // if (!error) + // { + // // Causes crash vga is not mapped in User Mode + // video::vga::text::write("Successfully made a SYSCALL and returned with SYSRETQ!", + // video::vga::text::common_attributes::green_on_black); + // } for (;;) { -- cgit v1.2.3