diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-01 11:12:20 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-01 11:12:20 +0200 |
| commit | 419f4bebff5745b46bf30092dc7a7ca43449ea2e (patch) | |
| tree | 4b509ca6da26eeadaec193440c936954e4367f4e /kernel | |
| parent | c30ba8bc8c1cf80a7e9b46e9f1a66dc1b409fcbd (diff) | |
| download | teachos-419f4bebff5745b46bf30092dc7a7ca43449ea2e.tar.xz teachos-419f4bebff5745b46bf30092dc7a7ca43449ea2e.zip | |
kernel/tests: implement basic simulated memory
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kapi/memory.cpp | 8 | ||||
| -rw-r--r-- | kernel/tests/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | kernel/tests/include/kernel/tests/simulated_memory.hpp | 19 | ||||
| -rw-r--r-- | kernel/tests/kapi/memory.cpp | 77 | ||||
| -rw-r--r-- | kernel/tests/src/main.cpp | 4 | ||||
| -rw-r--r-- | kernel/tests/src/simulated_memory.cpp | 33 |
6 files changed, 150 insertions, 5 deletions
diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 2803d76..06a3165 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -125,14 +125,18 @@ namespace kapi::memory } auto const flags = page_mapper::flags::writable | page_mapper::flags::supervisor_only | page_mapper::flags::global; + auto bitmap_ptr = static_cast<std::uint64_t *>(nullptr); std::ranges::for_each(std::views::iota(0uz, bitmap_pages), [&](auto index) { auto page = page::containing(pmm_metadata_base + index * page::size); auto frame = memory::frame(bitmap_frames->first.number() + index); - active_page_mapper->map(page, frame, flags); + auto mapped = active_page_mapper->map(page, frame, flags); + if (!bitmap_ptr) + { + bitmap_ptr = reinterpret_cast<std::uint64_t *>(mapped); + } }); - auto bitmap_ptr = static_cast<std::uint64_t *>(pmm_metadata_base); auto bitmap = std::span{bitmap_ptr, (bitmap_bytes + kstd::type_size<std::uint64_t> - 1_B) / kstd::type_size<std::uint64_t>}; diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt index 0e2ea36..0855520 100644 --- a/kernel/tests/CMakeLists.txt +++ b/kernel/tests/CMakeLists.txt @@ -7,9 +7,19 @@ add_library("kernel_test_support" "kapi/cpu.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" - + "src/log_buffer.cpp" "src/main.cpp" + "src/simulated_memory.cpp" +) + +file(GLOB_RECURSE KERNEL_TEST_SUPPORT_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") + +target_sources("kernel_test_support" PUBLIC + FILE_SET HEADERS + BASE_DIRS "include" + FILES + ${KERNEL_TEST_SUPPORT_HEADERS} ) target_include_directories("kernel_test_support" PUBLIC @@ -18,6 +28,7 @@ target_include_directories("kernel_test_support" PUBLIC target_link_libraries("kernel_test_support" PUBLIC "os::kapi" + "os::kernel" "Catch2::Catch2" ) @@ -37,7 +48,6 @@ target_include_directories("kernel_tests" PRIVATE target_link_libraries("kernel_tests" PRIVATE "os::kernel_test_support" - "os::kernel" "libs::kstd" ) diff --git a/kernel/tests/include/kernel/tests/simulated_memory.hpp b/kernel/tests/include/kernel/tests/simulated_memory.hpp new file mode 100644 index 0000000..156b1e1 --- /dev/null +++ b/kernel/tests/include/kernel/tests/simulated_memory.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP +#define TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP + +#include <kstd/units> + +#include <cstddef> + +namespace kernel::tests::simulated_memory +{ + + auto init(kstd::units::bytes size) -> void; + + auto pmm_metadata_base() -> std::byte *; + + auto ram_base() -> std::byte *; + +} // namespace kernel::tests::simulated_memory + +#endif
\ No newline at end of file diff --git a/kernel/tests/kapi/memory.cpp b/kernel/tests/kapi/memory.cpp index 4482c74..6de2f60 100644 --- a/kernel/tests/kapi/memory.cpp +++ b/kernel/tests/kapi/memory.cpp @@ -1,11 +1,86 @@ +#include "kapi/memory.hpp" + #include <kapi/memory.hpp> +#include "kernel/tests/simulated_memory.hpp" + +#include <kstd/print> +#include <kstd/units> + +#include <cstddef> +#include <cstdint> +#include <optional> +#include <utility> + namespace kapi::memory { + namespace + { + //! The size of the simulated RAM. + constexpr auto simulate_memory_size = kstd::units::MiB(32); + + struct test_boostrap_frame_allocator : frame_allocator + { + auto mark_used(frame) -> void override {} + + auto allocate_many(std::size_t count) noexcept -> std::optional<std::pair<frame, std::size_t>> override + { + auto start = next_free_frame; + next_free_frame += count; + return std::pair{frame{start}, count}; + } + + auto release_many(std::pair<frame, std::size_t>) -> void override {} + + std::size_t next_free_frame{}; + } boostrap_allocator; + + struct test_page_mapper : page_mapper + { + auto map(page page, frame frame, flags flags) -> std::byte * override + { + kstd::println("mapping page {} onto frame {} with flags {}", page.number(), frame.number(), + static_cast<std::uint64_t>(flags)); + + if ((page.start_address() & pmm_metadata_base.raw()) == pmm_metadata_base.raw()) + { + auto offset = page.start_address() & ~pmm_metadata_base.raw(); + return kernel::tests::simulated_memory::pmm_metadata_base() + offset; + } + + return nullptr; + } + + auto unmap(page page) -> void override + { + kstd::println("unmapping page {}", page.number()); + } + + auto try_unmap(page page) noexcept -> bool override + { + kstd::println("trying to unmap page {}", page.number()); + return false; + } + } test_mapper; + + auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void + { + for (auto i = 0uz; i < boostrap_allocator.next_free_frame; ++i) + { + new_allocator.mark_used(frame{i}); + } + } + + } // namespace + auto init() -> void { - // TODO: initialize simulated memory. + kernel::tests::simulated_memory::init(simulate_memory_size); + set_frame_allocator(boostrap_allocator); + set_page_mapper(test_mapper); + + init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); } } // namespace kapi::memory
\ No newline at end of file diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index c0ec12f..69fd633 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -12,6 +12,10 @@ auto main(int argc, char ** argv) -> int kapi::interrupts::enable(); kapi::memory::init(); + // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the memory + // subsystem, so that components that rely on it can be tested. No component must ever rely on the heap allocator + // directly, rather they have to go through the new and delete. However, some components may use the frame allocator + // and page mapper in order to perform their tasks. return Catch::Session().run(argc, argv); } diff --git a/kernel/tests/src/simulated_memory.cpp b/kernel/tests/src/simulated_memory.cpp new file mode 100644 index 0000000..9a9b354 --- /dev/null +++ b/kernel/tests/src/simulated_memory.cpp @@ -0,0 +1,33 @@ +#include "kernel/tests/simulated_memory.hpp" + +#include <kstd/units> + +#include <cstddef> +#include <vector> + +namespace kernel::tests::simulated_memory +{ + + namespace + { + auto constinit ram_storage = std::vector<std::byte>{}; + auto constinit pmm_storage = std::vector<std::byte>{}; + } // namespace + + auto init(kstd::units::bytes size) -> void + { + ram_storage.resize(size / kstd::units::bytes{1}); + pmm_storage.resize(size / kstd::units::bytes{1}); + } + + auto pmm_metadata_base() -> std::byte * + { + return pmm_storage.data(); + } + + auto ram_base() -> std::byte * + { + return ram_storage.data(); + } + +} // namespace kernel::tests::simulated_memory
\ No newline at end of file |
