29 {
31
32 auto& vm = VirtualMemorySingleton::instance();
33
34
38 "virtual_memory_test: failed to create user page directory");
40 klog::Info(
"virtual_memory_test: user page directory created at {}",
41 user_page_dir);
42
43
44 void* virt_addr = reinterpret_cast<void*>(0x200000);
45 void* phys_addr = reinterpret_cast<void*>(0x90000000);
46
47 auto map_result =
48 vm.MapPage(user_page_dir, virt_addr, phys_addr,
51 "virtual_memory_test: failed to map page");
52 klog::Info(
"virtual_memory_test: mapped va={} to pa={}", virt_addr,
53 phys_addr);
54
55
56 auto mapped = vm.GetMapping(user_page_dir, virt_addr);
57 EXPECT_TRUE(mapped.has_value(),
"virtual_memory_test: failed to get mapping");
58 if (mapped) {
60 "virtual_memory_test: mapping address mismatch");
61 klog::Info(
"virtual_memory_test: verified mapping pa={}", *mapped);
62 }
63
64
65 constexpr size_t kNumPages = 5;
66 for (size_t i = 0; i < kNumPages; ++i) {
67 void* va = reinterpret_cast<void*>(0x300000 +
69 void* pa = reinterpret_cast<void*>(0x91000000 +
71
72 auto result = vm.MapPage(user_page_dir, va, pa,
75 "virtual_memory_test: failed to map multiple pages");
76 }
77 klog::Info(
"virtual_memory_test: mapped {} pages", kNumPages);
78
79
80 for (size_t i = 0; i < kNumPages; ++i) {
81 void* va = reinterpret_cast<void*>(0x300000 +
83 void* pa = reinterpret_cast<void*>(0x91000000 +
85
86 auto m = vm.GetMapping(user_page_dir, va);
88 "virtual_memory_test: multiple page mapping not found");
89 if (m) {
90 EXPECT_EQ(*m, pa,
"virtual_memory_test: multiple page mapping mismatch");
91 }
92 }
93 klog::Info(
"virtual_memory_test: verified {} page mappings", kNumPages);
94
95
96 auto unmap_result = vm.UnmapPage(user_page_dir, virt_addr);
98 "virtual_memory_test: failed to unmap page");
99
100 auto unmapped = vm.GetMapping(user_page_dir, virt_addr);
102 "virtual_memory_test: page still mapped after unmap");
103 klog::Info(
"virtual_memory_test: unmapped va={}", virt_addr);
104
105
106 auto clone_result = vm.ClonePageDirectory(user_page_dir, true);
108 "virtual_memory_test: failed to clone page directory");
109 void* cloned_page_dir = clone_result.value();
111 "virtual_memory_test: cloned page dir same as source");
112 klog::Info(
"virtual_memory_test: cloned page directory to {}",
113 cloned_page_dir);
114
115
116 for (size_t i = 0; i < kNumPages; ++i) {
117 void* va = reinterpret_cast<void*>(0x300000 +
119 void* pa = reinterpret_cast<void*>(0x91000000 +
121
122 auto src_m = vm.GetMapping(user_page_dir, va);
123 auto dst_m = vm.GetMapping(cloned_page_dir, va);
124
126 "virtual_memory_test: source mapping lost after clone");
128 "virtual_memory_test: cloned mapping not found");
129
130 if (src_m && dst_m) {
132 "virtual_memory_test: source mapping changed after clone");
133 EXPECT_EQ(*dst_m, pa,
"virtual_memory_test: cloned mapping incorrect");
135 "virtual_memory_test: source and clone mappings differ");
136 }
137 }
138 klog::Info(
"virtual_memory_test: verified cloned mappings");
139
140
141 auto clone_no_map_result = vm.ClonePageDirectory(user_page_dir, false);
143 "virtual_memory_test: failed to clone page dir (no mappings)");
144 void* cloned_no_map = clone_no_map_result.value();
145 klog::Info(
"virtual_memory_test: cloned page directory (no mappings) to {}",
146 cloned_no_map);
147
148
149 for (size_t i = 0; i < kNumPages; ++i) {
150 void* va = reinterpret_cast<void*>(0x300000 +
152
153 auto m = vm.GetMapping(cloned_no_map, va);
155 "virtual_memory_test: cloned (no map) should have no mappings");
156 }
157 klog::Info(
"virtual_memory_test: verified no mappings in cloned page dir");
158
159
160 void* new_va = reinterpret_cast<void*>(0x400000);
161 void* new_pa = reinterpret_cast<void*>(0x92000000);
162
163 auto clone_map_result =
164 vm.MapPage(cloned_no_map, new_va, new_pa,
167 "virtual_memory_test: failed to map in cloned page dir");
168
169
170 auto user_m = vm.GetMapping(user_page_dir, new_va);
171 auto clone_m = vm.GetMapping(cloned_no_map, new_va);
172
174 "virtual_memory_test: mapping leaked to original page dir");
176 "virtual_memory_test: new mapping not in cloned page dir");
177 if (clone_m) {
179 "virtual_memory_test: new mapping address incorrect");
180 }
181 klog::Info(
"virtual_memory_test: verified independent mappings");
182
183
184 vm.DestroyPageDirectory(user_page_dir, false);
185 klog::Info(
"virtual_memory_test: destroyed user page directory");
186
187 vm.DestroyPageDirectory(cloned_page_dir, false);
188 klog::Info(
"virtual_memory_test: destroyed cloned page directory");
189
190 vm.DestroyPageDirectory(cloned_no_map, false);
191 klog::Info(
"virtual_memory_test: destroyed cloned (no map) page directory");
192
193
197 "virtual_memory_test: failed to create test page dir");
199
200 void* test_va = reinterpret_cast<void*>(0x500000);
201 void* test_pa1 = reinterpret_cast<void*>(0x93000000);
202 void* test_pa2 = reinterpret_cast<void*>(0x94000000);
203
204
205 (void)vm.MapPage(test_page_dir, test_va, test_pa1,
207
208 auto m1 = vm.GetMapping(test_page_dir, test_va);
209 EXPECT_TRUE(m1.has_value(),
"virtual_memory_test: first mapping failed");
210 if (m1) {
211 EXPECT_EQ(*m1, test_pa1,
"virtual_memory_test: first mapping incorrect");
212 }
213
214
215 (void)vm.MapPage(test_page_dir, test_va, test_pa2,
217
218 auto m2 = vm.GetMapping(test_page_dir, test_va);
219 EXPECT_TRUE(m2.has_value(),
"virtual_memory_test: remap failed");
220 if (m2) {
221 EXPECT_EQ(*m2, test_pa2,
"virtual_memory_test: remap address incorrect");
222 }
223 klog::Info(
"virtual_memory_test: verified remap from {} to {}", test_pa1,
224 test_pa2);
225
226
227 vm.DestroyPageDirectory(test_page_dir, false);
228
229 klog::Info(
"virtual_memory_test: all tests passed");
230 return true;
231}
static constexpr size_t kPageSize
auto GetUserPagePermissions(bool readable=true, bool writable=false, bool executable=false, bool global=false) -> uint64_t
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
void * aligned_alloc(size_t alignment, size_t size)
#define EXPECT_TRUE(cond, msg)
#define EXPECT_EQ(val1, val2, msg)