Skip to content

Commit

Permalink
fix: 初始映射多映点
Browse files Browse the repository at this point in the history
Signed-off-by: YdrMaster <[email protected]>
  • Loading branch information
YdrMaster committed Sep 5, 2022
1 parent 5b4b399 commit 227956d
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 47 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion xtask/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl QemuArgs {
.bin();
// 设置 Qemu 参数
let mut qemu = Qemu::system(arch_str);
qemu.args(&["-m", "1G"])
qemu.args(&["-m", "2G"])
.arg("-kernel")
.arg(&bin)
.arg("-initrd")
Expand Down
2 changes: 1 addition & 1 deletion zCore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ buddy_system_allocator = "0.8"
r0 = "1"
riscv = "0.8"
dtb-walker = "=0.2.0-alpha.3"
page-table = "0.0.2"
page-table = "0.0.4"
sbi-rt = { git = "https://github.com/rustsbi/sbi-rt.git", rev = "2933f8d" }

# Bare-metal mode on x86_64
Expand Down
2 changes: 1 addition & 1 deletion zCore/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use lock::Mutex;
type FrameAlloc = bitmap_allocator::BitAlloc16M; // max 64G

#[cfg(target_arch = "riscv64")]
type FrameAlloc = bitmap_allocator::BitAlloc1M; // max 4G
type FrameAlloc = bitmap_allocator::BitAlloc16M; // max 4G

#[cfg(target_arch = "aarch64")]
type FrameAlloc = bitmap_allocator::BitAlloc1M; // max 4G
Expand Down
60 changes: 20 additions & 40 deletions zCore/src/platform/riscv/boot_page_table.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,37 @@
use super::consts::{kernel_mem_info, kernel_mem_probe};
use core::arch::asm;
use page_table::{MmuFlags, PageTable, Sv39, OFFSET_BITS, PPN};

/// 内核页属性
const KERNEL_PAGE: MmuFlags<Sv39> = MmuFlags::new(0xef); // DAG_'XWRV

/// 子页表属性
const SUBTABLE: MmuFlags<Sv39> = MmuFlags::new(0x21); // __G_'___V
use page_table::{MmuFlags, PageTable, Sv39, VAddr, OFFSET_BITS, PPN};

/// 启动页表。
pub(super) struct BootPageTable {
root: PageTable<Sv39>,
sub: PageTable<Sv39>,
}
#[repr(align(4096))]
pub(super) struct BootPageTable(PageTable<Sv39>);

/// 内核页属性
const DAGXWRV: MmuFlags<Sv39> = MmuFlags::new(0xef);

impl BootPageTable {
/// 初始化为全零的启动页表。
pub const ZERO: Self = Self {
root: PageTable::ZERO,
sub: PageTable::ZERO,
};
pub const ZERO: Self = Self(PageTable::ZERO);

/// 根据内核实际位置初始化启动页表。
pub fn init(&mut self) {
// 启动页表初始化之前 pc 必定在物理地址空间
// 因此可以安全地定位内核地址信息
let mem_info = unsafe { kernel_mem_probe() };
let pbase = mem_info.paddr_base;
let vbase = mem_info.vaddr_base;
let paddr_base = mem_info.paddr_base & MASK1G;
let vaddr_base = mem_info.vaddr_base & MASK1G;
const MASK1G: usize = !((1 << 30) - 1);

const GIB_MASK: usize = !((1 << 30) - 1);
const SIZE_2MIB: usize = 1 << 21;
const MASK_2MIB: usize = !(SIZE_2MIB - 1);
{
// 把内核起始位置到其所在 GiB 页的末尾映射到虚拟地址空间
let mut p = (pbase & MASK_2MIB)..((pbase & GIB_MASK) + (1 << 30));
let mut v = vbase & MASK_2MIB;
while !p.is_empty() {
let entry = KERNEL_PAGE.build_pte(PPN(p.start >> OFFSET_BITS));
self.sub.set_entry(v.into(), entry, 1).unwrap();
p.start += SIZE_2MIB;
v += SIZE_2MIB;
}
// 内核 GiB 页表项
let pte = DAGXWRV.build_pte(PPN(paddr_base >> OFFSET_BITS));
// 映射内核页和跳板页
self.0.set_entry(VAddr::new(paddr_base), pte, 2).unwrap();
for i in 0..64 {
let paddr = paddr_base + (i << 30);
let vaddr = vaddr_base + (i << 30);
let pte = DAGXWRV.build_pte(PPN(paddr >> OFFSET_BITS));
self.0.set_entry(VAddr::new(vaddr), pte, 2).unwrap();
}
// 映射跳板页和内核页
let raw = KERNEL_PAGE.build_pte(PPN((pbase & GIB_MASK) >> OFFSET_BITS));
let sub = SUBTABLE.build_pte(PPN(self.sub.as_ptr() as usize >> OFFSET_BITS));
self.root
.set_entry((pbase & GIB_MASK).into(), raw, 2)
.unwrap();
self.root
.set_entry((vbase & GIB_MASK).into(), sub, 2)
.unwrap();
}

/// 启动地址转换,跃迁到高地址,并设置线程指针和内核对用户页的访问权限。
Expand All @@ -66,7 +46,7 @@ impl BootPageTable {
satp::set(
satp::Mode::Sv39,
0,
self.root.as_ptr() as usize >> OFFSET_BITS,
self as *const _ as usize >> OFFSET_BITS,
);
// 此时原本的地址空间还在,所以不用刷快表
// riscv::asm::sfence_vma_all();
Expand Down
2 changes: 1 addition & 1 deletion zCore/src/platform/riscv/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl KernelMemInfo {
fn end();
}
let paddr_base = start as usize;
let vaddr_base = ((!0) << 30) + (paddr_base & ((1 << 21) - 1));
let vaddr_base = 0xffff_ffe0_0020_0000;
Self {
paddr_base,
vaddr_base,
Expand Down
2 changes: 1 addition & 1 deletion zCore/src/platform/riscv/linker.ld
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)
BASE_ADDRESS = 0xffffffffc0000000;
BASE_ADDRESS = 0xffffffe000200000;
SECTIONS
{
. = BASE_ADDRESS;
Expand Down

0 comments on commit 227956d

Please sign in to comment.