|
|
|
@ -1,6 +1,11 @@
|
|
|
|
|
use alloc::collections::BTreeMap;
|
|
|
|
|
use alloc::sync::Arc;
|
|
|
|
|
use alloc::vec::Vec;
|
|
|
|
|
use core::arch::asm;
|
|
|
|
|
use bitflags::bitflags;
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
use riscv::register::satp;
|
|
|
|
|
use crate::sync::UPSafeCell;
|
|
|
|
|
use crate::config::{MEMORY_END, PAGE_SIZE, TRAMPOLINE};
|
|
|
|
|
use crate::mm::address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum, VPNRange};
|
|
|
|
|
use crate::mm::frame_allocator::{frame_alloc, FrameTracker};
|
|
|
|
@ -20,6 +25,11 @@ extern "C" {
|
|
|
|
|
fn ekernel();
|
|
|
|
|
fn strampoline(); // 这个符号 在linker.ld 中定义
|
|
|
|
|
}
|
|
|
|
|
lazy_static! {
|
|
|
|
|
/// a memory set instance through lazy_static! managing kernel space
|
|
|
|
|
pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> =
|
|
|
|
|
Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 某逻辑段的映射方式
|
|
|
|
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
|
|
|
@ -164,6 +174,21 @@ impl MemorySet {
|
|
|
|
|
self.page_table.token()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 激活当前地址空间
|
|
|
|
|
pub fn activate(&self) {
|
|
|
|
|
// let satp = self.page_table.token();
|
|
|
|
|
// 得到当前地址空间的 页表 的规定格式
|
|
|
|
|
let satp = self.token();;
|
|
|
|
|
unsafe {
|
|
|
|
|
// 设置satp CSR寄存器为我们
|
|
|
|
|
satp::write(satp);
|
|
|
|
|
|
|
|
|
|
// 刷新快表缓存TLB, 这个指令最简单的作用就是清空旧的快表
|
|
|
|
|
// 更深层次其实是一个内存屏障
|
|
|
|
|
asm!("sfence.vma");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据 start va 和end va 创建一个 逻辑段类型为逻辑映射, 插入到 当前地址空间
|
|
|
|
|
pub fn insert_framed_area(&mut self, start_va: VirtAddr, end_va: VirtAddr, permission: MapPermission) {
|
|
|
|
|
self.push(MapArea::from(start_va, end_va, MapType::Framed, permission), None);
|
|
|
|
|