SimpleKernel 1.17.0
Loading...
Searching...
No Matches
virtual_memory_test.cpp File Reference
#include "virtual_memory.hpp"
#include <cpu_io.h>
#include <cstddef>
#include <cstdint>
#include "arch.h"
#include "basic_info.hpp"
#include "kernel.h"
#include "kstd_cstring"
#include "kstd_libcxx.h"
#include "sk_stdlib.h"
#include "system_test.h"
Include dependency graph for virtual_memory_test.cpp:

Go to the source code of this file.

Functions

void * malloc (size_t size)
 
void free (void *ptr)
 
void * aligned_alloc (size_t alignment, size_t size)
 
auto virtual_memory_test () -> bool
 

Function Documentation

◆ aligned_alloc()

void * aligned_alloc ( size_t  alignment,
size_t  size 
)

Definition at line 58 of file memory.cpp.

58 {
59 if (allocator) {
60 return allocator->aligned_alloc(alignment, size);
61 }
62 return nullptr;
63}
Here is the caller graph for this function:

◆ free()

void free ( void *  ptr)

Definition at line 38 of file memory.cpp.

38 {
39 if (allocator) {
40 allocator->free(ptr);
41 }
42}

◆ malloc()

void * malloc ( size_t  size)

Definition at line 31 of file memory.cpp.

31 {
32 if (allocator) {
33 return allocator->malloc(size);
34 }
35 return nullptr;
36}

◆ virtual_memory_test()

auto virtual_memory_test ( ) -> bool

Definition at line 29 of file virtual_memory_test.cpp.

29 {
30 klog::Info("virtual_memory_test: start");
31
32 auto& vm = VirtualMemorySingleton::instance();
33
34 // Test 1: 创建用户页表
37 EXPECT_TRUE(user_page_dir != nullptr,
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 // Test 2: 映射页面
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,
50 EXPECT_TRUE(map_result.has_value(),
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 // Test 3: 获取映射
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) {
59 EXPECT_EQ(*mapped, phys_addr,
60 "virtual_memory_test: mapping address mismatch");
61 klog::Info("virtual_memory_test: verified mapping pa={}", *mapped);
62 }
63
64 // Test 4: 映射多个页面
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,
74 EXPECT_TRUE(result.has_value(),
75 "virtual_memory_test: failed to map multiple pages");
76 }
77 klog::Info("virtual_memory_test: mapped {} pages", kNumPages);
78
79 // Test 5: 验证多页映射
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);
87 EXPECT_TRUE(m.has_value(),
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 // Test 6: 取消映射
96 auto unmap_result = vm.UnmapPage(user_page_dir, virt_addr);
97 EXPECT_TRUE(unmap_result.has_value(),
98 "virtual_memory_test: failed to unmap page");
99
100 auto unmapped = vm.GetMapping(user_page_dir, virt_addr);
101 EXPECT_TRUE(!unmapped.has_value(),
102 "virtual_memory_test: page still mapped after unmap");
103 klog::Info("virtual_memory_test: unmapped va={}", virt_addr);
104
105 // Test 7: 克隆页表(复制映射)
106 auto clone_result = vm.ClonePageDirectory(user_page_dir, true);
107 EXPECT_TRUE(clone_result.has_value(),
108 "virtual_memory_test: failed to clone page directory");
109 void* cloned_page_dir = clone_result.value();
110 EXPECT_TRUE(cloned_page_dir != user_page_dir,
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 // Test 8: 验证克隆的映射
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
125 EXPECT_TRUE(src_m.has_value(),
126 "virtual_memory_test: source mapping lost after clone");
127 EXPECT_TRUE(dst_m.has_value(),
128 "virtual_memory_test: cloned mapping not found");
129
130 if (src_m && dst_m) {
131 EXPECT_EQ(*src_m, pa,
132 "virtual_memory_test: source mapping changed after clone");
133 EXPECT_EQ(*dst_m, pa, "virtual_memory_test: cloned mapping incorrect");
134 EXPECT_EQ(*src_m, *dst_m,
135 "virtual_memory_test: source and clone mappings differ");
136 }
137 }
138 klog::Info("virtual_memory_test: verified cloned mappings");
139
140 // Test 9: 克隆页表(不复制映射)
141 auto clone_no_map_result = vm.ClonePageDirectory(user_page_dir, false);
142 EXPECT_TRUE(clone_no_map_result.has_value(),
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);
154 EXPECT_TRUE(!m.has_value(),
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 // Test 10: 在克隆的页表中添加新映射
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,
166 EXPECT_TRUE(clone_map_result.has_value(),
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
173 EXPECT_TRUE(!user_m.has_value(),
174 "virtual_memory_test: mapping leaked to original page dir");
175 EXPECT_TRUE(clone_m.has_value(),
176 "virtual_memory_test: new mapping not in cloned page dir");
177 if (clone_m) {
178 EXPECT_EQ(*clone_m, new_pa,
179 "virtual_memory_test: new mapping address incorrect");
180 }
181 klog::Info("virtual_memory_test: verified independent mappings");
182
183 // Test 11: 销毁页表
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 // Test 12: 重新映射测试
196 EXPECT_TRUE(test_page_dir != nullptr,
197 "virtual_memory_test: failed to create test page dir");
198 memset(test_page_dir, 0, cpu_io::virtual_memory::kPageSize);
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
Definition cpu_io.h:63
auto GetUserPagePermissions(bool readable=true, bool writable=false, bool executable=false, bool global=false) -> uint64_t
Definition cpu_io.h:79
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
#define memset
void * aligned_alloc(size_t alignment, size_t size)
Definition memory.cpp:58
#define EXPECT_TRUE(cond, msg)
#define EXPECT_EQ(val1, val2, msg)
Here is the call graph for this function: