diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-01 20:59:55 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-01 20:59:55 +0200 |
| commit | dc64b1cba4677b40c9dda31ecd5109507837b817 (patch) | |
| tree | 9954f6d3bb07c78daa12e807eef8e828dc9b5fe0 /kernel | |
| parent | 825d8bafef152a52cd76851764913fb12cdc685d (diff) | |
| download | teachos-dc64b1cba4677b40c9dda31ecd5109507837b817.tar.xz teachos-dc64b1cba4677b40c9dda31ecd5109507837b817.zip | |
kernel/tests: don't rely on vector for fake memory
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/include/kernel/test_support/simulated_memory.hpp | 15 | ||||
| -rw-r--r-- | kernel/src/test_support/page_mapper.cpp | 20 | ||||
| -rw-r--r-- | kernel/src/test_support/simulated_memory.cpp | 77 |
3 files changed, 100 insertions, 12 deletions
diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp index fed9f43..9a391d8 100644 --- a/kernel/include/kernel/test_support/simulated_memory.hpp +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -1,10 +1,11 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP +#include "kapi/memory.hpp" + #include <kstd/units> #include <cstddef> -#include <vector> namespace kernel::tests { @@ -13,13 +14,21 @@ namespace kernel::tests { explicit simulated_memory(kstd::units::bytes size); + ~simulated_memory(); + auto clear() -> void; - auto ram_base() noexcept -> std::byte *; + [[nodiscard]] auto ram_base() noexcept -> std::byte *; [[nodiscard]] auto ram_base() const noexcept -> std::byte const *; + [[nodiscard]] auto heap_base() const noexcept -> kapi::memory::linear_address; + [[nodiscard]] auto heap_size() const noexcept -> kstd::units::bytes; + [[nodiscard]] auto memory_descriptor() const noexcept -> int; private: - std::vector<std::byte> m_memory; + int m_memory_descriptor{}; + kstd::units::bytes m_size{0}; + std::byte * m_physical_base{nullptr}; + std::byte * m_virtual_base{nullptr}; }; } // namespace kernel::tests diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp index 5a1b747..805998b 100644 --- a/kernel/src/test_support/page_mapper.cpp +++ b/kernel/src/test_support/page_mapper.cpp @@ -7,6 +7,7 @@ #include <cstddef> #include <format> #include <stdexcept> +#include <sys/mman.h> namespace kernel::tests { @@ -20,10 +21,25 @@ namespace kernel::tests page_mappings.insert({page.number(), frame}); auto page_address = page.start_address(); + auto sandbox_start = memory.heap_base(); + auto sandbox_end = sandbox_start + memory.heap_size(); - if (page_address >= kapi::memory::mmio_base) + if (page_address >= sandbox_start && page_address < sandbox_end) { - throw std::invalid_argument{"MMIO mapping not yet supported in testing!"}; + auto virtual_target = static_cast<std::byte *>(page_address); + auto physical_offset = frame.number() * kapi::memory::frame::size; + auto mapped_ptr = mmap(virtual_target, kapi::memory::page::size.value, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, memory.memory_descriptor(), physical_offset.value); + if (mapped_ptr == MAP_FAILED) + { + throw std::runtime_error("Failed to map page"); + } + + return static_cast<std::byte *>(mapped_ptr); + } + else if (page_address >= kapi::memory::mmio_base) + { + throw std::runtime_error("MMIO mapping not yet supported in testing!"); } else if (page_address >= kapi::memory::higher_half_direct_map_base) { diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 7264a35..fa3d36c 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -1,30 +1,93 @@ #include "kernel/test_support/simulated_memory.hpp" +#include "kapi/memory.hpp" + #include <kstd/units> #include <cstddef> -#include <vector> +#include <cstring> +#include <stdexcept> +#include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> + +using namespace kstd::units_literals; namespace kernel::tests { + namespace + { + constexpr auto virtual_size = 1_GiB; + } simulated_memory::simulated_memory(kstd::units::bytes size) - : m_memory{size / kstd::units::bytes{1}} - {} + : m_memory_descriptor{memfd_create("teachos_simulated_memory", 0)} + , m_size{size} + { + if (m_memory_descriptor < 0) + { + throw std::runtime_error("Failed to create simulated memory"); + } + + if (ftruncate(m_memory_descriptor, static_cast<off_t>(m_size.value)) < 0) + { + throw std::runtime_error("Failed to resize simulated memory"); + } + + auto mapped_pointer = mmap(nullptr, m_size.value, PROT_READ | PROT_WRITE, MAP_SHARED, m_memory_descriptor, 0); + if (mapped_pointer == MAP_FAILED) + { + throw std::runtime_error("Failed to map simulated memory"); + } + + m_physical_base = static_cast<std::byte *>(mapped_pointer); + + auto virtual_pointer = mmap(nullptr, virtual_size.value, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (virtual_pointer == MAP_FAILED) + { + throw std::runtime_error("Failed to map simulated memory"); + } + + m_virtual_base = static_cast<std::byte *>(virtual_pointer); + + clear(); + } + + simulated_memory::~simulated_memory() + { + munmap(m_physical_base, m_size.value); + munmap(m_virtual_base, virtual_size.value); + close(m_memory_descriptor); + } + + auto simulated_memory::clear() -> void + { + std::memset(m_physical_base, 0, m_size.value); + } auto simulated_memory::ram_base() noexcept -> std::byte * { - return m_memory.data(); + return m_physical_base; } auto simulated_memory::ram_base() const noexcept -> std::byte const * { - return m_memory.data(); + return m_physical_base; } - auto simulated_memory::clear() -> void + auto simulated_memory::heap_base() const noexcept -> kapi::memory::linear_address + { + return kapi::memory::linear_address{m_virtual_base}; + } + + auto simulated_memory::heap_size() const noexcept -> kstd::units::bytes + { + return virtual_size; + } + + auto simulated_memory::memory_descriptor() const noexcept -> int { - m_memory.clear(); + return m_memory_descriptor; } } // namespace kernel::tests
\ No newline at end of file |
