Checkpoint: kernel remap
This commit is contained in:
parent
791b0c5a3d
commit
7d64ab8335
|
@ -22,6 +22,22 @@ pub struct TrapFrame {
|
|||
sepc: usize,
|
||||
}
|
||||
|
||||
use core::fmt;
|
||||
impl fmt::Display for TrapFrame {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let x = self.x;
|
||||
writeln!(f, "")?;
|
||||
writeln!(f, "x0: {:016x}, ra: {:016x}, sp: {:016x}, gp: {:016x}", 0, x[1], x[2], x[3])?;
|
||||
writeln!(f, "tp: {:016x}, t0: {:016x}, t1: {:016x}, t2: {:016x}", x[4], x[5], x[6], x[7])?;
|
||||
writeln!(f, "s0: {:016x}, s1: {:016x}, a0: {:016x}, a1: {:016x}", x[8], x[9], x[10], x[11])?;
|
||||
writeln!(f, "a2: {:016x}, a3: {:016x}, a4: {:016x}, a5: {:016x}", x[12], x[13], x[14], x[15])?;
|
||||
writeln!(f, "a6: {:016x}, a7: {:016x}, s2: {:016x}, s3: {:016x}", x[16], x[17], x[18], x[19])?;
|
||||
writeln!(f, "s4: {:016x}, s5: {:016x}, s6: {:016x}, s7: {:016x}", x[20], x[21], x[22], x[23])?;
|
||||
writeln!(f, "s8: {:016x}, s9: {:016x}, s10:{:016x}, s11:{:016x}", x[24], x[25], x[26], x[27])?;
|
||||
writeln!(f, "t3: {:016x}, t4: {:016x}, t5: {:016x}, t6: {:016x}", x[28], x[29], x[30], x[31])
|
||||
}
|
||||
}
|
||||
|
||||
#[export_name = "rust_supervisor_timer"]
|
||||
pub extern "C" fn supervisor_timer(trap_frame: &mut TrapFrame) -> *mut TrapFrame {
|
||||
// panic!("Supervisor timer: {:08x}", sepc::read());
|
||||
|
@ -44,7 +60,7 @@ pub extern "C" fn trap_exception(trap_frame: &mut TrapFrame) -> *mut TrapFrame {
|
|||
match scause::read().cause() {
|
||||
Trap::Exception(Exception::Breakpoint) => breakpoint(trap_frame),
|
||||
Trap::Exception(e) =>
|
||||
panic!("Exception! {:?}, sepc: {:#08x}", e, sepc::read()),
|
||||
panic!("Exception! {:?}, sepc: {:#08x}, trap_frame: {}", e, sepc::read(), trap_frame),
|
||||
Trap::Interrupt(_) => unreachable!("SBI or CPU design fault")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ SECTIONS
|
|||
*(.sbss .bss .bss.*)
|
||||
_ebss = .;
|
||||
}
|
||||
|
||||
|
||||
. = ALIGN(4K);
|
||||
free_memory_start = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
|
|
|
@ -45,9 +45,7 @@ pub extern "C" fn rust_main() -> ! {
|
|||
}
|
||||
|
||||
println!("heap test passed");
|
||||
#[cfg(riscv)]
|
||||
let remap = memory::MemorySet::new_kernel().unwrap();
|
||||
#[cfg(riscv)]
|
||||
remap.activate();
|
||||
println!("kernel remapped");
|
||||
|
||||
|
|
|
@ -70,6 +70,11 @@ impl VirtualAddress {
|
|||
pub unsafe fn deref_virtual<T>(self) -> &'static mut T {
|
||||
&mut *(self.0 as *mut T)
|
||||
}
|
||||
// 线性映射下,得到物理地址对应的虚拟地址
|
||||
pub fn physical_address_linear(self) -> PhysicalAddress {
|
||||
let pa = self.0.wrapping_sub(KERNEL_MAP_OFFSET);
|
||||
PhysicalAddress(pa)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::Add<usize> for VirtualAddress {
|
||||
|
@ -88,7 +93,7 @@ impl core::ops::Sub<VirtualAddress> for VirtualAddress {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct VirtualPageNumber(usize);
|
||||
|
||||
impl VirtualPageNumber {
|
||||
|
@ -106,8 +111,9 @@ impl VirtualPageNumber {
|
|||
}
|
||||
// 线性映射下,得到虚拟页号对应的物理页号
|
||||
pub fn physical_page_number_linear(self) -> PhysicalPageNumber {
|
||||
let pa = self.0.wrapping_sub(KERNEL_MAP_OFFSET);
|
||||
PhysicalPageNumber(pa / PAGE_SIZE)
|
||||
let va = self.start_address();
|
||||
let pa = va.physical_address_linear();
|
||||
PhysicalPageNumber(pa.0 / PAGE_SIZE)
|
||||
}
|
||||
/// 对于Sv39,得到一、二、三级页号
|
||||
pub fn levels(&self) -> [usize; 3] {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::memory::PhysicalAddress;
|
||||
use crate::memory::{PhysicalAddress, VirtualAddress};
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub const KERNEL_HEAP_SIZE: usize = 0x80_0000;
|
||||
|
@ -6,11 +6,11 @@ pub const KERNEL_HEAP_SIZE: usize = 0x80_0000;
|
|||
pub const MEMORY_END_ADDRESS: PhysicalAddress = PhysicalAddress(0x8800_0000);
|
||||
|
||||
lazy_static! {
|
||||
pub static ref FREE_MEMORY_START: PhysicalAddress = {
|
||||
pub static ref FREE_MEMORY_START: VirtualAddress = {
|
||||
extern "C" {
|
||||
fn free_memory_start();
|
||||
}
|
||||
PhysicalAddress(free_memory_start as usize)
|
||||
VirtualAddress(free_memory_start as usize)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::algorithm::{Allocator, StackedAllocator};
|
||||
use crate::memory::{PhysicalAddress, PhysicalPageNumber, frame::FrameTracker};
|
||||
use crate::memory::{PhysicalPageNumber, frame::FrameTracker};
|
||||
use crate::memory::config::{FREE_MEMORY_START, MEMORY_END_ADDRESS};
|
||||
use core::ops::Range;
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -8,7 +8,7 @@ use spin::Mutex;
|
|||
lazy_static! {
|
||||
/// 帧分配器
|
||||
pub static ref FRAME_ALLOCATOR: Mutex<FrameAllocator<StackedAllocator>> = {
|
||||
let pa_start = PhysicalAddress::from(*FREE_MEMORY_START);
|
||||
let pa_start = FREE_MEMORY_START.physical_address_linear();
|
||||
let ppn_start = PhysicalPageNumber::ceil(pa_start);
|
||||
let ppn_end = PhysicalPageNumber::floor(MEMORY_END_ADDRESS);
|
||||
return Mutex::new(FrameAllocator::new(
|
||||
|
|
|
@ -126,14 +126,22 @@ impl Mapping {
|
|||
None
|
||||
}
|
||||
/// 把当前的映射保存到satp寄存器
|
||||
#[cfg(riscv)]
|
||||
pub fn activate(&self) {
|
||||
use riscv::{register::satp::{self, Mode}, asm};
|
||||
// use riscv::{register::satp::{self, Mode}, asm};
|
||||
// unsafe {
|
||||
// // 保存到satp寄存器
|
||||
// satp::set(Mode::Sv39, 0 /* asid */, self.root_ppn.into());
|
||||
// // 刷新页表缓存
|
||||
// asm::sfence_vma_all();
|
||||
// }
|
||||
// satp 低 27 位为页号,高 4 位为模式,8 表示 Sv39
|
||||
let root_ppn: usize = self.root_ppn.into();
|
||||
let new_satp = root_ppn | (8 << 60);
|
||||
unsafe {
|
||||
// 保存到satp寄存器
|
||||
satp::set(Mode::Sv39, 0 /* asid */, self.root_ppn.into());
|
||||
// 刷新页表缓存
|
||||
asm::sfence_vma_all();
|
||||
// 将 new_satp 的值写到 satp 寄存器
|
||||
llvm_asm!("csrw satp, $0" :: "r"(new_satp) :: "volatile");
|
||||
// 刷新 TLB
|
||||
llvm_asm!("sfence.vma" :::: "volatile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +157,9 @@ fn range_vpn_contains_va(src: Range<VirtualAddress>) -> Range<VirtualPageNumber>
|
|||
|
||||
// 一个虚拟页号段区间的迭代器
|
||||
struct VpnRangeIter {
|
||||
// 区间结束,不包含
|
||||
end_addr: usize,
|
||||
// 区间开始,包含
|
||||
current_addr: usize,
|
||||
}
|
||||
|
||||
|
@ -159,11 +169,11 @@ impl Iterator for VpnRangeIter {
|
|||
if self.current_addr == self.end_addr {
|
||||
return None;
|
||||
}
|
||||
// 这里只要右移12位即可,ceil和floor区别不大
|
||||
let current_vpn = VirtualPageNumber::ceil(VirtualAddress(self.current_addr));
|
||||
let next_addr = self.current_addr.wrapping_add(PAGE_SIZE);
|
||||
let next_va = VirtualAddress(next_addr);
|
||||
let next_vpn = VirtualPageNumber::ceil(next_va);
|
||||
self.current_addr = next_addr;
|
||||
Some(next_vpn)
|
||||
Some(current_vpn)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,12 @@ impl MemorySet {
|
|||
fn _sbss();
|
||||
fn _ebss();
|
||||
}
|
||||
|
||||
println!("text: {:x?}", VirtualAddress(_stext as usize)..VirtualAddress(_etext as usize));
|
||||
println!("rodata: {:x?}", VirtualAddress(_srodata as usize)..VirtualAddress(_erodata as usize));
|
||||
println!("data: {:x?}", VirtualAddress(_sdata as usize)..VirtualAddress(_edata as usize));
|
||||
println!("bss: {:x?}", VirtualAddress(_sbss as usize)..VirtualAddress(_ebss as usize));
|
||||
println!("free: {:x?}", *FREE_MEMORY_START..MEMORY_END_ADDRESS.virtual_address_linear());
|
||||
|
||||
// 建立字段
|
||||
let segments = vec![
|
||||
|
@ -37,25 +43,25 @@ impl MemorySet {
|
|||
// .rodata 段,r--
|
||||
Segment {
|
||||
map_type: MapType::Linear,
|
||||
range: VirtualAddress(_stext as usize)..VirtualAddress(_etext as usize),
|
||||
range: VirtualAddress(_srodata as usize)..VirtualAddress(_erodata as usize),
|
||||
flags: Flags::READABLE,
|
||||
},
|
||||
// .data 段,rw-
|
||||
Segment {
|
||||
map_type: MapType::Linear,
|
||||
range: VirtualAddress(_stext as usize)..VirtualAddress(_etext as usize),
|
||||
range: VirtualAddress(_sdata as usize)..VirtualAddress(_edata as usize),
|
||||
flags: Flags::READABLE | Flags::WRITABLE,
|
||||
},
|
||||
// .bss 段,rw-
|
||||
Segment {
|
||||
map_type: MapType::Linear,
|
||||
range: VirtualAddress(_stext as usize)..VirtualAddress(_etext as usize),
|
||||
range: VirtualAddress(_sbss as usize)..VirtualAddress(_ebss as usize),
|
||||
flags: Flags::READABLE | Flags::WRITABLE,
|
||||
},
|
||||
// 剩余内存空间,rw-
|
||||
Segment {
|
||||
map_type: MapType::Linear,
|
||||
range: FREE_MEMORY_START.virtual_address_linear()..MEMORY_END_ADDRESS.virtual_address_linear(),
|
||||
range: *FREE_MEMORY_START..MEMORY_END_ADDRESS.virtual_address_linear(),
|
||||
flags: Flags::READABLE | Flags::WRITABLE,
|
||||
},
|
||||
];
|
||||
|
@ -71,7 +77,6 @@ impl MemorySet {
|
|||
/// 替换 `satp` 以激活页表
|
||||
///
|
||||
/// 如果当前页表就是自身,则不会替换,但仍然会刷新 TLB。
|
||||
#[cfg(riscv)]
|
||||
pub fn activate(&self) {
|
||||
self.mapping.activate()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue