From 5c14673fe01ca63895ada25a328f3de78a3d4d4d Mon Sep 17 00:00:00 2001 From: WangRunji Date: Tue, 10 Jul 2018 17:37:38 +0800 Subject: [PATCH] Setup a simple page table, enable paging. --- crate/riscv | 2 +- src/arch/riscv32/mod.rs | 17 +++++++++- src/arch/riscv32/paging.rs | 20 +++++++++++ src/consts.rs | 68 +++++++++++++++++++++++++------------- 4 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 src/arch/riscv32/paging.rs diff --git a/crate/riscv b/crate/riscv index 4bf5f1b..1022571 160000 --- a/crate/riscv +++ b/crate/riscv @@ -1 +1 @@ -Subproject commit 4bf5f1b732b8977d445f668df0b3f11c0d19d9a5 +Subproject commit 1022571b07f946add5187f2933f0dabe5819309b diff --git a/src/arch/riscv32/mod.rs b/src/arch/riscv32/mod.rs index 256c764..aece3db 100644 --- a/src/arch/riscv32/mod.rs +++ b/src/arch/riscv32/mod.rs @@ -4,10 +4,25 @@ extern crate bbl; pub mod serial; pub mod interrupt; pub mod timer; +pub mod paging; pub fn init() { println!("Hello RISCV! {}", 123); interrupt::init(); - timer::init(); +// timer::init(); + println!("satp: {:x?}", riscv::register::satp::read()); + + use xmas_elf::ElfFile; + use core::slice; + use self::riscv::addr::*; + let begin = 0x80400000usize; + extern { fn end(); } + let end = end as usize; + println!("Kernel: {:#x} {:#x}", begin, end); +// let kernel = unsafe{ slice::from_raw_parts(begin as *const u8, end - begin) }; +// let elf = ElfFile::new(kernel).unwrap(); + + paging::setup_page_table(Frame::of_addr(PhysAddr::new(end as u32 + 4096))); + loop {} } \ No newline at end of file diff --git a/src/arch/riscv32/paging.rs b/src/arch/riscv32/paging.rs new file mode 100644 index 0000000..1442b34 --- /dev/null +++ b/src/arch/riscv32/paging.rs @@ -0,0 +1,20 @@ +pub use super::riscv::paging::*; +pub use super::riscv::addr::*; + +// need 1 page +pub fn setup_page_table(frame: Frame) { + let p2 = unsafe { &mut *(frame.start_address().as_u32() as *mut PageTable) }; + p2.zero(); + + use self::PageTableFlags as F; + use consts::{KERNEL_PML4, RECURSIVE_PAGE_PML4}; + // Set recursive map + p2[RECURSIVE_PAGE_PML4].set(frame.clone(), F::VALID); + // Set kernel identity map + p2[KERNEL_PML4].set(Frame::of_addr(PhysAddr::new((KERNEL_PML4 as u32) << 22)), F::VALID | F::READABLE | F::WRITABLE | F::EXCUTABLE); + p2[KERNEL_PML4 + 1].set(Frame::of_addr(PhysAddr::new((KERNEL_PML4 as u32 + 1) << 22)), F::VALID | F::READABLE | F::WRITABLE | F::EXCUTABLE); + + use super::riscv::register::satp; + unsafe { satp::set(satp::Mode::Sv32, 0, frame); } + println!("New page table"); +} \ No newline at end of file diff --git a/src/consts.rs b/src/consts.rs index f259632..b99af94 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -2,30 +2,51 @@ pub const MAX_CPU_NUM: usize = 8; pub const MAX_PROCESS_NUM: usize = 32; -// Copy from Redox consts.rs: +#[cfg(target_arch = "riscv")] +pub use self::riscv::*; + +#[cfg(target_arch = "x86_64")] +pub use self::x86_64::*; + +#[cfg(target_arch = "riscv")] +mod riscv { + // Physical address available on THINPAD: + // [0x80000000, 0x80800000] + const P2_SIZE: usize = 1 << 22; + const P2_MASK: usize = 0x3ff << 22; + pub const RECURSIVE_PAGE_PML4: usize = 0x3ff; + pub const KERNEL_OFFSET: usize = 0; + pub const KERNEL_PML4: usize = 0x8040_0000 >> 22; + pub const KERNEL_HEAP_OFFSET: usize = 0x8000_0000; + pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024; // 8 MB +} + +#[cfg(target_arch = "x86_64")] +mod x86_64 { + // Copy from Redox consts.rs: -// Because the memory map is so important to not be aliased, it is defined here, in one place -// The lower 256 PML4 entries are reserved for userspace -// Each PML4 entry references up to 512 GB of memory -// The top (511) PML4 is reserved for recursive mapping -// The second from the top (510) PML4 is reserved for the kernel + // Because the memory map is so important to not be aliased, it is defined here, in one place + // The lower 256 PML4 entries are reserved for userspace + // Each PML4 entry references up to 512 GB of memory + // The top (511) PML4 is reserved for recursive mapping + // The second from the top (510) PML4 is reserved for the kernel /// The size of a single PML4 pub const PML4_SIZE: usize = 0x0000_0080_0000_0000; pub const PML4_MASK: usize = 0x0000_ff80_0000_0000; /// Offset of recursive paging pub const RECURSIVE_PAGE_OFFSET: usize = (-(PML4_SIZE as isize)) as usize; - pub const RECURSIVE_PAGE_PML4: usize = (RECURSIVE_PAGE_OFFSET & PML4_MASK)/PML4_SIZE; + pub const RECURSIVE_PAGE_PML4: usize = (RECURSIVE_PAGE_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset of kernel pub const KERNEL_OFFSET: usize = RECURSIVE_PAGE_OFFSET - PML4_SIZE; - pub const KERNEL_PML4: usize = (KERNEL_OFFSET & PML4_MASK)/PML4_SIZE; + pub const KERNEL_PML4: usize = (KERNEL_OFFSET & PML4_MASK) / PML4_SIZE; pub const KERNEL_SIZE: usize = PML4_SIZE; /// Offset to kernel heap pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET - PML4_SIZE; - pub const KERNEL_HEAP_PML4: usize = (KERNEL_HEAP_OFFSET & PML4_MASK)/PML4_SIZE; + pub const KERNEL_HEAP_PML4: usize = (KERNEL_HEAP_OFFSET & PML4_MASK) / PML4_SIZE; /// Size of kernel heap pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024; // 8 MB @@ -37,62 +58,63 @@ pub const MAX_PROCESS_NUM: usize = 32; /// Offset to user image pub const USER_OFFSET: usize = 0; - pub const USER_PML4: usize = (USER_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_PML4: usize = (USER_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user TCB pub const USER_TCB_OFFSET: usize = 0xB000_0000; /// Offset to user arguments - pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2; + pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE / 2; /// Offset to user heap pub const USER_HEAP_OFFSET: usize = USER_OFFSET + PML4_SIZE; - pub const USER_HEAP_PML4: usize = (USER_HEAP_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_HEAP_PML4: usize = (USER_HEAP_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user grants pub const USER_GRANT_OFFSET: usize = USER_HEAP_OFFSET + PML4_SIZE; - pub const USER_GRANT_PML4: usize = (USER_GRANT_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_GRANT_PML4: usize = (USER_GRANT_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user stack pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE; - pub const USER_STACK_PML4: usize = (USER_STACK_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_STACK_PML4: usize = (USER_STACK_OFFSET & PML4_MASK) / PML4_SIZE; /// Size of user stack pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB /// Offset to user sigstack pub const USER_SIGSTACK_OFFSET: usize = USER_STACK_OFFSET + PML4_SIZE; - pub const USER_SIGSTACK_PML4: usize = (USER_SIGSTACK_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_SIGSTACK_PML4: usize = (USER_SIGSTACK_OFFSET & PML4_MASK) / PML4_SIZE; /// Size of user sigstack pub const USER_SIGSTACK_SIZE: usize = 256 * 1024; // 256 KB /// Offset to user TLS pub const USER_TLS_OFFSET: usize = USER_SIGSTACK_OFFSET + PML4_SIZE; - pub const USER_TLS_PML4: usize = (USER_TLS_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TLS_PML4: usize = (USER_TLS_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user temporary image (used when cloning) pub const USER_TMP_OFFSET: usize = USER_TLS_OFFSET + PML4_SIZE; - pub const USER_TMP_PML4: usize = (USER_TMP_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_PML4: usize = (USER_TMP_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user temporary heap (used when cloning) pub const USER_TMP_HEAP_OFFSET: usize = USER_TMP_OFFSET + PML4_SIZE; - pub const USER_TMP_HEAP_PML4: usize = (USER_TMP_HEAP_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_HEAP_PML4: usize = (USER_TMP_HEAP_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user temporary page for grants pub const USER_TMP_GRANT_OFFSET: usize = USER_TMP_HEAP_OFFSET + PML4_SIZE; - pub const USER_TMP_GRANT_PML4: usize = (USER_TMP_GRANT_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_GRANT_PML4: usize = (USER_TMP_GRANT_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user temporary stack (used when cloning) pub const USER_TMP_STACK_OFFSET: usize = USER_TMP_GRANT_OFFSET + PML4_SIZE; - pub const USER_TMP_STACK_PML4: usize = (USER_TMP_STACK_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_STACK_PML4: usize = (USER_TMP_STACK_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user temporary sigstack (used when cloning) pub const USER_TMP_SIGSTACK_OFFSET: usize = USER_TMP_STACK_OFFSET + PML4_SIZE; - pub const USER_TMP_SIGSTACK_PML4: usize = (USER_TMP_SIGSTACK_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_SIGSTACK_PML4: usize = (USER_TMP_SIGSTACK_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset to user temporary tls (used when cloning) pub const USER_TMP_TLS_OFFSET: usize = USER_TMP_SIGSTACK_OFFSET + PML4_SIZE; - pub const USER_TMP_TLS_PML4: usize = (USER_TMP_TLS_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_TLS_PML4: usize = (USER_TMP_TLS_OFFSET & PML4_MASK) / PML4_SIZE; /// Offset for usage in other temporary pages pub const USER_TMP_MISC_OFFSET: usize = USER_TMP_TLS_OFFSET + PML4_SIZE; - pub const USER_TMP_MISC_PML4: usize = (USER_TMP_MISC_OFFSET & PML4_MASK)/PML4_SIZE; + pub const USER_TMP_MISC_PML4: usize = (USER_TMP_MISC_OFFSET & PML4_MASK) / PML4_SIZE; +} \ No newline at end of file