全局的内存管理器的分配和释放物理页帧完成
parent
c239525dc4
commit
d4069b8cde
@ -1,3 +1,14 @@
|
||||
pub mod heap_allocator;
|
||||
pub mod address;
|
||||
pub mod frame_allocator;
|
||||
|
||||
|
||||
|
||||
pub fn init(){
|
||||
// 开启 内核的内存分配器
|
||||
heap_allocator::init_heap();
|
||||
// 初始化bin测试 物理页帧管理器
|
||||
frame_allocator::frame_allocator_test();
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
use alloc::vec::Vec;
|
||||
use bitflags::*;
|
||||
use crate::mm::address::PhysPageNum;
|
||||
|
||||
|
||||
bitflags! {
|
||||
pub struct PTEFlags: u8 {
|
||||
const V = 1 << 0; // 仅当位 V 为 1 时,页表项才是合法的
|
||||
const R = 1 << 1; // 可读标志
|
||||
const W = 1 << 2; // 可写标志
|
||||
const X = 1 << 3; // 可执行标志
|
||||
const U = 1 << 4; // 是否允许U级访问
|
||||
const G = 1 << 5; //
|
||||
const A = 1 << 6; // 从上次清零之后, 该页是否被访问过
|
||||
const D = 1 << 7; // 从上次清零之后, 该页是否被修改过
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
/// pte结构体
|
||||
///
|
||||
/// 对应的64个字节的布局为
|
||||
///
|
||||
/// 10bit(保留) | 44bit(物理页号) | 10bit(标志位)
|
||||
pub struct PageTableEntry {
|
||||
pub bits: usize,
|
||||
}
|
||||
|
||||
|
||||
impl PageTableEntry {
|
||||
// 从一个物理页号和一个flag 创建出来一个 PTE
|
||||
// 物理也好 左移10位 加上 flag 即可
|
||||
pub fn from(ppn: PhysPageNum, flags: PTEFlags) -> Self {
|
||||
PageTableEntry {
|
||||
bits: ppn.0 << 10 | flags.bits as usize,
|
||||
}
|
||||
}
|
||||
|
||||
// 生成一个全0的PTE, V也是0, 它是不合法的
|
||||
pub fn new() -> Self {
|
||||
PageTableEntry { bits: 0 }
|
||||
}
|
||||
|
||||
// 从PTE中的到 物理页的地址, 右移bit flag的宽度 再只保留44位即可得到 usize类型的物理页号, 随后调用into进行转换
|
||||
pub fn ppn(&self) -> PhysPageNum {
|
||||
(self.bits >> 10 & ((1usize << 44) - 1)).into()
|
||||
}
|
||||
// 从PTE中得到bit flag
|
||||
pub fn flags(&self) -> PTEFlags {
|
||||
PTEFlags::from_bits(self.bits as u8).unwrap()
|
||||
}
|
||||
|
||||
// 判断是否合法, 只保留 V标志的位置, 再判断是否为0
|
||||
pub fn is_valid(&self) -> bool {
|
||||
(self.flags() & PTEFlags::V) != PTEFlags::empty()
|
||||
}
|
||||
// 判断是否可读
|
||||
pub fn readable(&self) -> bool {
|
||||
(self.flags() & PTEFlags::R) != PTEFlags::empty()
|
||||
}
|
||||
// 判断是否可写
|
||||
pub fn writable(&self) -> bool {
|
||||
(self.flags() & PTEFlags::W) != PTEFlags::empty()
|
||||
}
|
||||
// 判断是否可执行
|
||||
pub fn executable(&self) -> bool {
|
||||
(self.flags() & PTEFlags::X) != PTEFlags::empty()
|
||||
}
|
||||
}
|
||||
|
||||
// 页表
|
||||
pub struct PageTable {
|
||||
root_ppn: PhysPageNum,
|
||||
// 这里保存的是页表每一页所占的物理页帧的页号
|
||||
frames: Vec<FrameTracker>,
|
||||
}
|
Loading…
Reference in New Issue