#include "kernel/test_support/simulated_memory.hpp" #include "kapi/memory.hpp" #include #include #include #include #include #include #include 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_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(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(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(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_physical_base; } auto simulated_memory::ram_base() const noexcept -> std::byte const * { return m_physical_base; } 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 { return m_memory_descriptor; } } // namespace kernel::tests