1 use alloc::sync::Arc;
2
3 use crate::{
4 arch::MMArch,
5 include::bindings::bindings::{process_control_block, PAGE_OFFSET},
6 syscall::SystemError,
7 };
8
9 use core::{
10 cmp,
11 fmt::Debug,
12 intrinsics::unlikely,
13 ops::{Add, AddAssign, Sub, SubAssign},
14 ptr,
15 sync::atomic::{AtomicBool, Ordering},
16 };
17
18 use self::{
19 allocator::page_frame::{VirtPageFrame, VirtPageFrameIter},
20 page::round_up_to_page_size,
21 ucontext::{AddressSpace, UserMapper},
22 };
23
24 pub mod allocator;
25 pub mod c_adapter;
26 pub mod kernel_mapper;
27 pub mod mmio_buddy;
28 pub mod no_init;
29 pub mod page;
30 pub mod percpu;
31 pub mod syscall;
32 pub mod ucontext;
33
34 /// 内核INIT进程的用户地址空间结构体(仅在process_init中初始化)
35 static mut __INITIAL_PROCESS_ADDRESS_SPACE: Option<Arc<AddressSpace>> = None;
36
37 /// 获取内核INIT进程的用户地址空间结构体
38 #[allow(non_snake_case)]
39 #[inline(always)]
INITIAL_PROCESS_ADDRESS_SPACE() -> Arc<AddressSpace>40 pub fn INITIAL_PROCESS_ADDRESS_SPACE() -> Arc<AddressSpace> {
41 unsafe {
42 return __INITIAL_PROCESS_ADDRESS_SPACE
43 .as_ref()
44 .expect("INITIAL_PROCESS_ADDRESS_SPACE is null")
45 .clone();
46 }
47 }
48
49 /// 设置内核INIT进程的用户地址空间结构体全局变量
50 #[allow(non_snake_case)]
set_INITIAL_PROCESS_ADDRESS_SPACE(address_space: Arc<AddressSpace>)51 pub unsafe fn set_INITIAL_PROCESS_ADDRESS_SPACE(address_space: Arc<AddressSpace>) {
52 static INITIALIZED: AtomicBool = AtomicBool::new(false);
53 if INITIALIZED
54 .compare_exchange(false, true, Ordering::SeqCst, Ordering::Acquire)
55 .is_err()
56 {
57 panic!("INITIAL_PROCESS_ADDRESS_SPACE is already initialized");
58 }
59 __INITIAL_PROCESS_ADDRESS_SPACE = Some(address_space);
60 }
61
62 /// @brief 将内核空间的虚拟地址转换为物理地址
63 #[inline(always)]
virt_2_phys(addr: usize) -> usize64 pub fn virt_2_phys(addr: usize) -> usize {
65 addr - PAGE_OFFSET as usize
66 }
67
68 /// @brief 将物理地址转换为内核空间的虚拟地址
69 #[inline(always)]
phys_2_virt(addr: usize) -> usize70 pub fn phys_2_virt(addr: usize) -> usize {
71 addr + PAGE_OFFSET as usize
72 }
73
74 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
75 pub enum PageTableKind {
76 /// 用户可访问的页表
77 User,
78 /// 内核页表
79 Kernel,
80 }
81
82 /// 物理内存地址
83 #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)]
84 #[repr(transparent)]
85 pub struct PhysAddr(usize);
86
87 impl PhysAddr {
88 #[inline(always)]
new(address: usize) -> Self89 pub const fn new(address: usize) -> Self {
90 Self(address)
91 }
92
93 /// @brief 获取物理地址的值
94 #[inline(always)]
data(&self) -> usize95 pub fn data(&self) -> usize {
96 self.0
97 }
98
99 /// @brief 将物理地址加上一个偏移量
100 #[inline(always)]
add(self, offset: usize) -> Self101 pub fn add(self, offset: usize) -> Self {
102 Self(self.0 + offset)
103 }
104
105 /// @brief 判断物理地址是否按照指定要求对齐
106 #[inline(always)]
check_aligned(&self, align: usize) -> bool107 pub fn check_aligned(&self, align: usize) -> bool {
108 return self.0 & (align - 1) == 0;
109 }
110
111 #[inline(always)]
is_null(&self) -> bool112 pub fn is_null(&self) -> bool {
113 return self.0 == 0;
114 }
115 }
116
117 impl Debug for PhysAddr {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119 write!(f, "PhysAddr({:#x})", self.0)
120 }
121 }
122
123 impl core::ops::Add<usize> for PhysAddr {
124 type Output = Self;
125
126 #[inline(always)]
add(self, rhs: usize) -> Self::Output127 fn add(self, rhs: usize) -> Self::Output {
128 return Self(self.0 + rhs);
129 }
130 }
131
132 impl core::ops::AddAssign<usize> for PhysAddr {
133 #[inline(always)]
add_assign(&mut self, rhs: usize)134 fn add_assign(&mut self, rhs: usize) {
135 self.0 += rhs;
136 }
137 }
138
139 impl core::ops::Add<PhysAddr> for PhysAddr {
140 type Output = Self;
141
142 #[inline(always)]
add(self, rhs: PhysAddr) -> Self::Output143 fn add(self, rhs: PhysAddr) -> Self::Output {
144 return Self(self.0 + rhs.0);
145 }
146 }
147
148 impl core::ops::AddAssign<PhysAddr> for PhysAddr {
149 #[inline(always)]
add_assign(&mut self, rhs: PhysAddr)150 fn add_assign(&mut self, rhs: PhysAddr) {
151 self.0 += rhs.0;
152 }
153 }
154
155 impl core::ops::Sub<usize> for PhysAddr {
156 type Output = Self;
157
158 #[inline(always)]
sub(self, rhs: usize) -> Self::Output159 fn sub(self, rhs: usize) -> Self::Output {
160 return Self(self.0 - rhs);
161 }
162 }
163
164 impl core::ops::SubAssign<usize> for PhysAddr {
165 #[inline(always)]
sub_assign(&mut self, rhs: usize)166 fn sub_assign(&mut self, rhs: usize) {
167 self.0 -= rhs;
168 }
169 }
170
171 impl core::ops::Sub<PhysAddr> for PhysAddr {
172 type Output = usize;
173
174 #[inline(always)]
sub(self, rhs: PhysAddr) -> Self::Output175 fn sub(self, rhs: PhysAddr) -> Self::Output {
176 return self.0 - rhs.0;
177 }
178 }
179
180 impl core::ops::SubAssign<PhysAddr> for PhysAddr {
181 #[inline(always)]
sub_assign(&mut self, rhs: PhysAddr)182 fn sub_assign(&mut self, rhs: PhysAddr) {
183 self.0 -= rhs.0;
184 }
185 }
186
187 /// 虚拟内存地址
188 #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)]
189 #[repr(transparent)]
190 pub struct VirtAddr(usize);
191
192 impl VirtAddr {
193 #[inline(always)]
new(address: usize) -> Self194 pub const fn new(address: usize) -> Self {
195 return Self(address);
196 }
197
198 /// @brief 获取虚拟地址的值
199 #[inline(always)]
data(&self) -> usize200 pub fn data(&self) -> usize {
201 return self.0;
202 }
203
204 /// @brief 判断虚拟地址的类型
205 #[inline(always)]
kind(&self) -> PageTableKind206 pub fn kind(&self) -> PageTableKind {
207 if self.check_user() {
208 return PageTableKind::User;
209 } else {
210 return PageTableKind::Kernel;
211 }
212 }
213
214 /// @brief 判断虚拟地址是否按照指定要求对齐
215 #[inline(always)]
check_aligned(&self, align: usize) -> bool216 pub fn check_aligned(&self, align: usize) -> bool {
217 return self.0 & (align - 1) == 0;
218 }
219
220 /// @brief 判断虚拟地址是否在用户空间
221 #[inline(always)]
check_user(&self) -> bool222 pub fn check_user(&self) -> bool {
223 if self < &MMArch::USER_END_VADDR {
224 return true;
225 } else {
226 return false;
227 }
228 }
229
230 #[inline(always)]
as_ptr<T>(self) -> *mut T231 pub fn as_ptr<T>(self) -> *mut T {
232 return self.0 as *mut T;
233 }
234
235 #[inline(always)]
is_null(&self) -> bool236 pub fn is_null(&self) -> bool {
237 return self.0 == 0;
238 }
239 }
240
241 impl Add<VirtAddr> for VirtAddr {
242 type Output = Self;
243
244 #[inline(always)]
add(self, rhs: VirtAddr) -> Self::Output245 fn add(self, rhs: VirtAddr) -> Self::Output {
246 return Self(self.0 + rhs.0);
247 }
248 }
249
250 impl Add<usize> for VirtAddr {
251 type Output = Self;
252
253 #[inline(always)]
add(self, rhs: usize) -> Self::Output254 fn add(self, rhs: usize) -> Self::Output {
255 return Self(self.0 + rhs);
256 }
257 }
258
259 impl Sub<VirtAddr> for VirtAddr {
260 type Output = usize;
261
262 #[inline(always)]
sub(self, rhs: VirtAddr) -> Self::Output263 fn sub(self, rhs: VirtAddr) -> Self::Output {
264 return self.0 - rhs.0;
265 }
266 }
267
268 impl Sub<usize> for VirtAddr {
269 type Output = Self;
270
271 #[inline(always)]
sub(self, rhs: usize) -> Self::Output272 fn sub(self, rhs: usize) -> Self::Output {
273 return Self(self.0 - rhs);
274 }
275 }
276
277 impl AddAssign<usize> for VirtAddr {
278 #[inline(always)]
add_assign(&mut self, rhs: usize)279 fn add_assign(&mut self, rhs: usize) {
280 self.0 += rhs;
281 }
282 }
283
284 impl AddAssign<VirtAddr> for VirtAddr {
285 #[inline(always)]
add_assign(&mut self, rhs: VirtAddr)286 fn add_assign(&mut self, rhs: VirtAddr) {
287 self.0 += rhs.0;
288 }
289 }
290
291 impl SubAssign<usize> for VirtAddr {
292 #[inline(always)]
sub_assign(&mut self, rhs: usize)293 fn sub_assign(&mut self, rhs: usize) {
294 self.0 -= rhs;
295 }
296 }
297
298 impl SubAssign<VirtAddr> for VirtAddr {
299 #[inline(always)]
sub_assign(&mut self, rhs: VirtAddr)300 fn sub_assign(&mut self, rhs: VirtAddr) {
301 self.0 -= rhs.0;
302 }
303 }
304
305 impl Debug for VirtAddr {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result306 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
307 write!(f, "VirtAddr({:#x})", self.0)
308 }
309 }
310
311 /// @brief 物理内存区域
312 #[derive(Clone, Copy, Debug)]
313 pub struct PhysMemoryArea {
314 /// 物理基地址
315 pub base: PhysAddr,
316 /// 该区域的物理内存大小
317 pub size: usize,
318 }
319
320 pub trait MemoryManagementArch: Clone + Copy + Debug {
321 /// 页面大小的shift(假如页面4K,那么这个值就是12,因为2^12=4096)
322 const PAGE_SHIFT: usize;
323 /// 每个页表的页表项数目。(以2^n次幂来表示)假如有512个页表项,那么这个值就是9
324 const PAGE_ENTRY_SHIFT: usize;
325 /// 页表层级数量
326 const PAGE_LEVELS: usize;
327
328 /// 页表项的有效位的index(假如页表项的第0-51位有效,那么这个值就是52)
329 const ENTRY_ADDRESS_SHIFT: usize;
330 /// 页面的页表项的默认值
331 const ENTRY_FLAG_DEFAULT_PAGE: usize;
332 /// 页表的页表项的默认值
333 const ENTRY_FLAG_DEFAULT_TABLE: usize;
334 /// 页表项的present位被置位之后的值
335 const ENTRY_FLAG_PRESENT: usize;
336 /// 页表项为read only时的值
337 const ENTRY_FLAG_READONLY: usize;
338 /// 页表项为可读写状态的值
339 const ENTRY_FLAG_READWRITE: usize;
340 /// 页面项标记页面为user page的值
341 const ENTRY_FLAG_USER: usize;
342 /// 页面项标记页面为write through的值
343 const ENTRY_FLAG_WRITE_THROUGH: usize;
344 /// 页面项标记页面为cache disable的值
345 const ENTRY_FLAG_CACHE_DISABLE: usize;
346 /// 标记当前页面不可执行的标志位(Execute disable)(也就是说,不能从这段内存里面获取处理器指令)
347 const ENTRY_FLAG_NO_EXEC: usize;
348 /// 标记当前页面可执行的标志位(Execute enable)
349 const ENTRY_FLAG_EXEC: usize;
350
351 /// 虚拟地址与物理地址的偏移量
352 const PHYS_OFFSET: usize;
353
354 /// 每个页面的大小
355 const PAGE_SIZE: usize = 1 << Self::PAGE_SHIFT;
356 /// 通过这个mask,获取地址的页内偏移量
357 const PAGE_OFFSET_MASK: usize = Self::PAGE_SIZE - 1;
358 /// 页表项的地址、数据部分的shift。
359 /// 打个比方,如果这个值为52,那么意味着页表项的[0, 52)位,用于表示地址以及其他的标志位
360 const PAGE_ADDRESS_SHIFT: usize = Self::PAGE_LEVELS * Self::PAGE_ENTRY_SHIFT + Self::PAGE_SHIFT;
361 /// 最大的虚拟地址(对于不同的架构,由于上述PAGE_ADDRESS_SHIFT可能包括了reserved bits, 事实上能表示的虚拟地址应该比这个值要小)
362 const PAGE_ADDRESS_SIZE: usize = 1 << Self::PAGE_ADDRESS_SHIFT;
363 /// 页表项的值与这个常量进行与运算,得到的结果是所填写的物理地址
364 const PAGE_ADDRESS_MASK: usize = Self::PAGE_ADDRESS_SIZE - Self::PAGE_SIZE;
365 /// 每个页表项的大小
366 const PAGE_ENTRY_SIZE: usize = 1 << (Self::PAGE_SHIFT - Self::PAGE_ENTRY_SHIFT);
367 /// 每个页表的页表项数目
368 const PAGE_ENTRY_NUM: usize = 1 << Self::PAGE_ENTRY_SHIFT;
369 /// 该字段用于根据虚拟地址,获取该虚拟地址在对应的页表中是第几个页表项
370 const PAGE_ENTRY_MASK: usize = Self::PAGE_ENTRY_NUM - 1;
371
372 const PAGE_NEGATIVE_MASK: usize = !((Self::PAGE_ADDRESS_SIZE) - 1);
373
374 const ENTRY_ADDRESS_SIZE: usize = 1 << Self::ENTRY_ADDRESS_SHIFT;
375 /// 该mask用于获取页表项中地址字段
376 const ENTRY_ADDRESS_MASK: usize = Self::ENTRY_ADDRESS_SIZE - Self::PAGE_SIZE;
377 /// 这个mask用于获取页表项中的flags
378 const ENTRY_FLAGS_MASK: usize = !Self::ENTRY_ADDRESS_MASK;
379
380 /// 用户空间的最高地址
381 const USER_END_VADDR: VirtAddr;
382 /// 用户堆的起始地址
383 const USER_BRK_START: VirtAddr;
384 /// 用户栈起始地址(向下生长,不包含该值)
385 const USER_STACK_START: VirtAddr;
386
387 /// @brief 用于初始化内存管理模块与架构相关的信息。
388 /// 该函数应调用其他模块的接口,生成内存区域结构体,提供给BumpAllocator使用
init() -> &'static [PhysMemoryArea]389 unsafe fn init() -> &'static [PhysMemoryArea];
390
391 /// @brief 读取指定虚拟地址的值,并假设它是类型T的指针
392 #[inline(always)]
read<T>(address: VirtAddr) -> T393 unsafe fn read<T>(address: VirtAddr) -> T {
394 return ptr::read(address.data() as *const T);
395 }
396
397 /// @brief 将value写入到指定的虚拟地址
398 #[inline(always)]
write<T>(address: VirtAddr, value: T)399 unsafe fn write<T>(address: VirtAddr, value: T) {
400 ptr::write(address.data() as *mut T, value);
401 }
402
403 #[inline(always)]
write_bytes(address: VirtAddr, value: u8, count: usize)404 unsafe fn write_bytes(address: VirtAddr, value: u8, count: usize) {
405 ptr::write_bytes(address.data() as *mut u8, value, count);
406 }
407
408 /// @brief 刷新TLB中,关于指定虚拟地址的条目
invalidate_page(address: VirtAddr)409 unsafe fn invalidate_page(address: VirtAddr);
410
411 /// @brief 刷新TLB中,所有的条目
invalidate_all()412 unsafe fn invalidate_all();
413
414 /// @brief 获取顶级页表的物理地址
table(table_kind: PageTableKind) -> PhysAddr415 unsafe fn table(table_kind: PageTableKind) -> PhysAddr;
416
417 /// @brief 设置顶级页表的物理地址到处理器中
set_table(table_kind: PageTableKind, table: PhysAddr)418 unsafe fn set_table(table_kind: PageTableKind, table: PhysAddr);
419
420 /// @brief 将物理地址转换为虚拟地址.
421 ///
422 /// @param phys 物理地址
423 ///
424 /// @return 转换后的虚拟地址。如果转换失败,返回None
425 #[inline(always)]
phys_2_virt(phys: PhysAddr) -> Option<VirtAddr>426 unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> {
427 if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) {
428 return Some(VirtAddr::new(vaddr));
429 } else {
430 return None;
431 }
432 }
433
434 /// 将虚拟地址转换为物理地址
435 ///
436 /// ## 参数
437 ///
438 /// - `virt` 虚拟地址
439 ///
440 /// ## 返回值
441 ///
442 /// 转换后的物理地址。如果转换失败,返回None
443 #[inline(always)]
virt_2_phys(virt: VirtAddr) -> Option<PhysAddr>444 unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> {
445 if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) {
446 return Some(PhysAddr::new(paddr));
447 } else {
448 return None;
449 }
450 }
451
452 /// @brief 判断指定的虚拟地址是否正确(符合规范)
virt_is_valid(virt: VirtAddr) -> bool453 fn virt_is_valid(virt: VirtAddr) -> bool;
454
455 /// 获取内存管理初始化时,创建的第一个内核页表的地址
initial_page_table() -> PhysAddr456 fn initial_page_table() -> PhysAddr;
457
458 /// 初始化新的usermapper,为用户进程创建页表
setup_new_usermapper() -> Result<UserMapper, SystemError>459 fn setup_new_usermapper() -> Result<UserMapper, SystemError>;
460 }
461
462 /// @brief 虚拟地址范围
463 /// 该结构体用于表示一个虚拟地址范围,包括起始地址与大小
464 ///
465 /// 请注意与VMA进行区分,该结构体被VMA所包含
466 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
467 pub struct VirtRegion {
468 start: VirtAddr,
469 size: usize,
470 }
471
472 #[allow(dead_code)]
473 impl VirtRegion {
474 /// # 创建一个新的虚拟地址范围
new(start: VirtAddr, size: usize) -> Self475 pub fn new(start: VirtAddr, size: usize) -> Self {
476 VirtRegion { start, size }
477 }
478
479 /// 获取虚拟地址范围的起始地址
480 #[inline(always)]
start(&self) -> VirtAddr481 pub fn start(&self) -> VirtAddr {
482 self.start
483 }
484
485 /// 获取虚拟地址范围的截止地址(不包括返回的地址)
486 #[inline(always)]
end(&self) -> VirtAddr487 pub fn end(&self) -> VirtAddr {
488 return self.start().add(self.size);
489 }
490
491 /// # Create a new VirtRegion from a range [start, end)
492 ///
493 /// If end <= start, return None
between(start: VirtAddr, end: VirtAddr) -> Option<Self>494 pub fn between(start: VirtAddr, end: VirtAddr) -> Option<Self> {
495 if unlikely(end.data() <= start.data()) {
496 return None;
497 }
498 let size = end.data() - start.data();
499 return Some(VirtRegion::new(start, size));
500 }
501
502 /// # 取两个虚拟地址范围的交集
503 ///
504 /// 如果两个虚拟地址范围没有交集,返回None
intersect(&self, other: &VirtRegion) -> Option<VirtRegion>505 pub fn intersect(&self, other: &VirtRegion) -> Option<VirtRegion> {
506 let start = self.start.max(other.start);
507 let end = self.end().min(other.end());
508 return VirtRegion::between(start, end);
509 }
510
511 /// 设置虚拟地址范围的起始地址
512 #[inline(always)]
set_start(&mut self, start: VirtAddr)513 pub fn set_start(&mut self, start: VirtAddr) {
514 self.start = start;
515 }
516
517 #[inline(always)]
size(&self) -> usize518 pub fn size(&self) -> usize {
519 self.size
520 }
521
522 /// 设置虚拟地址范围的大小
523 #[inline(always)]
set_size(&mut self, size: usize)524 pub fn set_size(&mut self, size: usize) {
525 self.size = size;
526 }
527
528 /// 判断虚拟地址范围是否为空
529 #[inline(always)]
is_empty(&self) -> bool530 pub fn is_empty(&self) -> bool {
531 self.size == 0
532 }
533
534 /// 将虚拟地址区域的大小向上对齐到页大小
535 #[inline(always)]
round_up_size_to_page(self) -> Self536 pub fn round_up_size_to_page(self) -> Self {
537 return VirtRegion::new(self.start, round_up_to_page_size(self.size));
538 }
539
540 /// 判断两个虚拟地址范围是否由于具有交集而导致冲突
541 #[inline(always)]
collide(&self, other: &VirtRegion) -> bool542 pub fn collide(&self, other: &VirtRegion) -> bool {
543 return self.intersect(other).is_some();
544 }
545
iter_pages(&self) -> VirtPageFrameIter546 pub fn iter_pages(&self) -> VirtPageFrameIter {
547 return VirtPageFrame::iter_range(
548 VirtPageFrame::new(self.start),
549 VirtPageFrame::new(self.end()),
550 );
551 }
552
553 /// 获取[self.start(), region.start())的虚拟地址范围
554 ///
555 /// 如果self.start() >= region.start(),返回None
before(self, region: &VirtRegion) -> Option<Self>556 pub fn before(self, region: &VirtRegion) -> Option<Self> {
557 return Self::between(self.start(), region.start());
558 }
559
560 /// 获取[region.end(),self.end())的虚拟地址范围
561 ///
562 /// 如果 self.end() >= region.end() ,返回None
after(self, region: &VirtRegion) -> Option<Self>563 pub fn after(self, region: &VirtRegion) -> Option<Self> {
564 // if self.end() > region.end() none
565 return Self::between(region.end(), self.end());
566 }
567
568 /// 把当前虚拟地址范围内的某个虚拟地址,转换为另一个虚拟地址范围内的虚拟地址
569 ///
570 /// 如果vaddr不在当前虚拟地址范围内,返回None
571 ///
572 /// 如果vaddr在当前虚拟地址范围内,返回vaddr在new_base中的虚拟地址
rebase(self, vaddr: VirtAddr, new_base: &VirtRegion) -> Option<VirtAddr>573 pub fn rebase(self, vaddr: VirtAddr, new_base: &VirtRegion) -> Option<VirtAddr> {
574 if !self.contains(vaddr) {
575 return None;
576 }
577 let offset = vaddr.data() - self.start().data();
578 let new_start = new_base.start().data() + offset;
579 return Some(VirtAddr::new(new_start));
580 }
581
582 /// 判断虚拟地址范围是否包含指定的虚拟地址
contains(&self, addr: VirtAddr) -> bool583 pub fn contains(&self, addr: VirtAddr) -> bool {
584 return self.start() <= addr && addr < self.end();
585 }
586
587 /// 创建当前虚拟地址范围的页面迭代器
pages(&self) -> VirtPageFrameIter588 pub fn pages(&self) -> VirtPageFrameIter {
589 return VirtPageFrame::iter_range(
590 VirtPageFrame::new(self.start()),
591 VirtPageFrame::new(self.end()),
592 );
593 }
594 }
595
596 impl PartialOrd for VirtRegion {
partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>597 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
598 return self.start.partial_cmp(&other.start);
599 }
600 }
601
602 impl Ord for VirtRegion {
cmp(&self, other: &Self) -> cmp::Ordering603 fn cmp(&self, other: &Self) -> cmp::Ordering {
604 return self.start.cmp(&other.start);
605 }
606 }
607
608 /// ## 判断虚拟地址是否超出了用户空间
609 ///
610 /// 如果虚拟地址超出了用户空间,返回Err(SystemError::EFAULT).
611 /// 如果end < start,返回Err(SystemError::EOVERFLOW)
612 ///
613 /// 否则返回Ok(())
verify_area(addr: VirtAddr, size: usize) -> Result<(), SystemError>614 pub fn verify_area(addr: VirtAddr, size: usize) -> Result<(), SystemError> {
615 let end = addr.add(size);
616 if unlikely(end.data() < addr.data()) {
617 return Err(SystemError::EOVERFLOW);
618 }
619
620 if !addr.check_user() || !end.check_user() {
621 return Err(SystemError::EFAULT);
622 }
623
624 return Ok(());
625 }
626 // ====== 重构内存管理、进程管理后,请删除这几行 BEGIN ======
627 //BUG pcb问题
628 unsafe impl Send for process_control_block {}
629 unsafe impl Sync for process_control_block {}
630
631 // ====== 重构内存管理后,请删除这几行 END =======
632