1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#include "kernel/test_support/simulated_memory.hpp"
#include "kapi/memory.hpp"
#include <kstd/units>
#include <cstddef>
#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_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_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
|