Skip to main content

tg_kernel_vm/
lib.rs

1//! 内核虚存管理。
2//!
3//! 教程阅读建议:
4//!
5//! - 先从 [`PageManager`] trait 入手,明确“页分配/页表根/虚实地址转换”职责;
6//! - 再阅读 `AddressSpace` 的 map/unmap/translate,理解章节中地址空间操作主路径。
7
8#![no_std]
9#![deny(warnings, missing_docs)]
10
11mod space;
12
13pub extern crate page_table;
14pub use space::AddressSpace;
15
16use core::ptr::NonNull;
17use page_table::{Pte, VmFlags, VmMeta, PPN};
18
19/// 物理页管理。
20pub trait PageManager<Meta: VmMeta> {
21    /// 新建根页表页。
22    fn new_root() -> Self;
23
24    /// 获取根页表。
25    fn root_ptr(&self) -> NonNull<Pte<Meta>>;
26
27    /// 获取根页表的物理页号。
28    #[inline]
29    fn root_ppn(&self) -> PPN<Meta> {
30        self.v_to_p(self.root_ptr())
31    }
32
33    /// 计算当前地址空间上指向物理页的指针。
34    fn p_to_v<T>(&self, ppn: PPN<Meta>) -> NonNull<T>;
35
36    /// 计算当前地址空间上的指针指向的物理页。
37    fn v_to_p<T>(&self, ptr: NonNull<T>) -> PPN<Meta>;
38
39    /// 检查是否拥有一个页的所有权。
40    fn check_owned(&self, pte: Pte<Meta>) -> bool;
41
42    /// 为地址空间分配 `len` 个物理页。
43    ///
44    /// `flags` 允许分配器按策略回填页属性(例如 COW 或自定义位)。
45    fn allocate(&mut self, len: usize, flags: &mut VmFlags<Meta>) -> NonNull<u8>;
46
47    /// 从地址空间释放 `pte` 指示的 `len` 个物理页。
48    fn deallocate(&mut self, pte: Pte<Meta>, len: usize) -> usize;
49
50    /// 释放根页表。
51    fn drop_root(&mut self);
52}