From 0dbffbc0fa52d9e0b88c62117dc32dc397623ffd Mon Sep 17 00:00:00 2001 From: dzy Date: Wed, 26 Dec 2018 00:12:10 +0800 Subject: [PATCH] temporary --- crate/bit-allocator/src/lib.rs | 1 + crate/memory/Cargo.toml | 2 +- crate/memory/src/lib.rs | 2 +- crate/memory/src/memory_set.rs | 11 +++++-- crate/riscv | 2 +- kernel/Cargo.lock | 1 + kernel/Makefile | 2 +- kernel/run-qemu-script-custom-llc | 5 +-- kernel/src/arch/riscv32/consts.rs | 20 +++++++++-- kernel/src/arch/riscv32/memory.rs | 19 ++++++++++- kernel/src/arch/riscv32/paging.rs | 55 ++++++++++++++++++++++++++----- kernel/src/memory.rs | 21 +++++++++--- 12 files changed, 115 insertions(+), 26 deletions(-) diff --git a/crate/bit-allocator/src/lib.rs b/crate/bit-allocator/src/lib.rs index c2c94a3d..f097f038 100644 --- a/crate/bit-allocator/src/lib.rs +++ b/crate/bit-allocator/src/lib.rs @@ -77,6 +77,7 @@ impl BitAlloc for BitAllocCascade16 { impl BitAllocCascade16 { fn for_range(&mut self, range: Range, f: impl Fn(&mut T, Range)) { let Range { start, end } = range; + assert!(start <= end); assert!(end <= Self::CAP); for i in start / T::CAP..=(end - 1) / T::CAP { let begin = if start / T::CAP == i { start % T::CAP } else { 0 }; diff --git a/crate/memory/Cargo.toml b/crate/memory/Cargo.toml index 309f0a8c..3a9dd209 100644 --- a/crate/memory/Cargo.toml +++ b/crate/memory/Cargo.toml @@ -5,4 +5,4 @@ authors = ["WangRunji "] edition = "2018" [dependencies] -log = "0.4" \ No newline at end of file +log = "0.4" diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs index ac956fa9..83a201ae 100644 --- a/crate/memory/src/lib.rs +++ b/crate/memory/src/lib.rs @@ -14,4 +14,4 @@ pub mod memory_set; mod addr; pub mod no_mmu; -pub use crate::addr::*; \ No newline at end of file +pub use crate::addr::*; diff --git a/crate/memory/src/memory_set.rs b/crate/memory/src/memory_set.rs index 3c631eb5..ececa404 100644 --- a/crate/memory/src/memory_set.rs +++ b/crate/memory/src/memory_set.rs @@ -298,9 +298,16 @@ impl MemorySet { } } pub fn new_bare() -> Self { + info!("new bare"); + // TODO + info!("Vec::new begin"); + let a = Vec::::new(); + info!("Vec::new finish"); + let pt = T::new_bare(); + info!("T::new bare finish"); MemorySet { - areas: Vec::::new(), - page_table: T::new_bare(), + areas: a, + page_table: pt, } } /* diff --git a/crate/riscv b/crate/riscv index e31e34a7..03033e95 160000 --- a/crate/riscv +++ b/crate/riscv @@ -1 +1 @@ -Subproject commit e31e34a7d97a52946ed8762ddb435318c9c3b8ac +Subproject commit 03033e9570079f85476280de4e155ef21d6c9e8b diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 5a31da9c..02555f85 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -236,6 +236,7 @@ dependencies = [ "bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/kernel/Makefile b/kernel/Makefile index 2ca538a3..fb96ca9c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -181,7 +181,7 @@ ifeq ($(arch), riscv32) $(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \ src/arch/riscv32/atomic.patch endif - @CC=$(cc) cargo xbuild $(build_args) + @CC=$(cc) LOG=trace cargo xbuild $(build_args) endif diff --git a/kernel/run-qemu-script-custom-llc b/kernel/run-qemu-script-custom-llc index dc41422b..9097784b 100755 --- a/kernel/run-qemu-script-custom-llc +++ b/kernel/run-qemu-script-custom-llc @@ -19,7 +19,7 @@ fi if ! [[ ${RV32} = 1 ]]; then TARGET_ARCH=riscv64 - export LOG=info + export LOG=trace COMPILER_RT_CFLAGS="-march=rv64ia -mabi=lp64 -O3" SFSIMG_CFLAGS="-march=rv64ia -mabi=lp64" RISCV_PK_CONFIGURE_FLAGS="--with-arch=rv64imac --disable-fp-emulation --host=riscv64-unknown-elf" @@ -466,6 +466,7 @@ rustc --crate-name riscv ../crate/riscv/src/lib.rs \ --extern bare_metal=$PWD/outdir/libbare_metal.rlib \ --extern bit_field=$PWD/outdir/libbit_field.rlib \ --extern bitflags=$PWD/outdir/libbitflags.rlib \ + --extern log=$PWD/outdir/liblog.rlib \ --cap-lints allow gen_full_rlib fi @@ -575,7 +576,7 @@ else mkdir -p build && cd build ../configure ${RISCV_PK_CONFIGURE_FLAGS} \ --with-payload=../../kernel/outdir/ucore - make + make -j32 cp bbl ../../kernel/outdir/kernel.bin cd ../../kernel ${QEMU} -smp cores=4 -nographic -machine virt -kernel outdir/kernel.bin diff --git a/kernel/src/arch/riscv32/consts.rs b/kernel/src/arch/riscv32/consts.rs index 3765a430..4bc47ea3 100644 --- a/kernel/src/arch/riscv32/consts.rs +++ b/kernel/src/arch/riscv32/consts.rs @@ -3,20 +3,34 @@ #[cfg(target_arch = "riscv32")] pub const RECURSIVE_INDEX: usize = 0x3fe; #[cfg(target_arch = "riscv64")] -pub const RECURSIVE_INDEX: usize = 0x1fe; +pub const RECURSIVE_INDEX: usize = 0x1fd; +// Under riscv64, upon booting, paging is enabled by bbl and +// root_table[0777] maps to p3_table, +// and p3_table[0776] maps to gigapage 8000_0000H, +// so 0xFFFF_FFFF_8000_0000 maps to 0x8000_0000 +// root_table[0775] points to root_table itself as page table +// root_table[0776] points to root_table itself as leaf page +#[cfg(target_arch = "riscv32")] pub const KERNEL_P2_INDEX: usize = 0x8000_0000 >> 22; + #[cfg(feature = "board_k210")] pub const KERNEL_HEAP_SIZE: usize = 0x0010_0000; #[cfg(not(feature = "board_k210"))] pub const KERNEL_HEAP_SIZE: usize = 0x00a0_0000; + #[cfg(feature = "board_k210")] pub const MEMORY_OFFSET: usize = 0x4000_0000; -#[cfg(not(feature = "board_k210"))] +#[cfg(target_arch = "riscv32")] pub const MEMORY_OFFSET: usize = 0x8000_0000; +#[cfg(all(target_arch = "riscv64", not(feature = "board_k210")))] +pub const MEMORY_OFFSET: usize = 0x8000_0000; + +#[cfg(target_arch = "riscv32")] +pub const MEMORY_END: usize = 0x8100_0000; #[cfg(feature = "board_k210")] pub const MEMORY_END: usize = 0x4060_0000; -#[cfg(not(feature = "board_k210"))] +#[cfg(all(target_arch = "riscv64", not(feature = "board_k210")))] pub const MEMORY_END: usize = 0x8100_0000; pub const USER_STACK_OFFSET: usize = 0x70000000; diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index cbd2a6eb..e31a24c2 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -4,6 +4,7 @@ use ucore_memory::PAGE_SIZE; use log::*; use crate::memory::{active_table, FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet, MEMORY_ALLOCATOR}; use crate::consts::{MEMORY_OFFSET, MEMORY_END}; +use riscv::register::satp; #[cfg(feature = "no_mmu")] pub fn init() { @@ -27,6 +28,7 @@ pub fn init() { init_heap(); // remap the kernel use 4K page remap_the_kernel(); + loop { } } pub fn init_other() { @@ -44,9 +46,14 @@ fn init_frame_allocator() { use bit_allocator::BitAlloc; use core::ops::Range; + // TODO: delete debug code let mut ba = FRAME_ALLOCATOR.lock(); - ba.insert(to_range(end as usize + PAGE_SIZE, MEMORY_END)); + let range = to_range((end as usize) - 0xFFFF_FFFF_0000_0000 + PAGE_SIZE, MEMORY_END); + info!("FrameAllocator insert {} .. {}", range.start, range.end); + ba.insert(range); info!("FrameAllocator init end"); + // DEBUG: trace code + trace!("init_frame_allocator: alloc={:x?}", ba.alloc()); /* * @param: @@ -60,6 +67,7 @@ fn init_frame_allocator() { fn to_range(start: usize, end: usize) -> Range { let page_start = (start - MEMORY_OFFSET) / PAGE_SIZE; let page_end = (end - MEMORY_OFFSET - 1) / PAGE_SIZE + 1; + assert!(page_start < page_end, "illegal range for frame allocator"); page_start..page_end } } @@ -83,16 +91,25 @@ fn remap_the_kernel() { #[cfg(all(target_arch = "riscv64", not(feature = "no_mmu")))] fn remap_the_kernel() { + info!("remap the kernel begin, satp: {:x}", satp::read().bits()); let mut ms = MemorySet::new_bare(); + info!("ms new bare"); #[cfg(feature = "no_bbl")] ms.push(MemoryArea::new_identity(0x0000_0000_1000_0000, 0x0000_0000_1000_0008, MemoryAttr::default(), "serial")); ms.push(MemoryArea::new_identity(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), "text")); + info!("ms new ident text"); ms.push(MemoryArea::new_identity(sdata as usize, edata as usize, MemoryAttr::default(), "data")); + info!("ms new ident data"); ms.push(MemoryArea::new_identity(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), "rodata")); + info!("ms new ident rodata"); ms.push(MemoryArea::new_identity(bootstack as usize, bootstacktop as usize, MemoryAttr::default(), "stack")); + info!("ms new ident rodatistack"); ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss")); + info!("ms push finish"); unsafe { ms.activate(); } + info!("ms activate finish"); unsafe { SATP = ms.token(); } + info!("satp token ok"); mem::forget(ms); info!("kernel remap end"); } diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 00b8de21..2ee16d7b 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -1,4 +1,4 @@ -use crate::consts::{KERNEL_P2_INDEX, RECURSIVE_INDEX}; +use crate::consts::RECURSIVE_INDEX; // Depends on kernel use crate::memory::{active_table, alloc_frame, dealloc_frame}; use riscv::addr::*; @@ -10,6 +10,8 @@ use ucore_memory::memory_set::*; use ucore_memory::PAGE_SIZE; use ucore_memory::paging::*; use log::*; +#[cfg(target_arch = "riscv32")] +use crate::consts::KERNEL_P2_INDEX; pub struct ActivePageTable(RecursivePageTable<'static>); @@ -35,6 +37,7 @@ impl PageTable for ActivePageTable { let frame = Frame::of_addr(PhysAddr::new(target)); // map the page to the frame using FrameAllocatorForRiscv // we may need frame allocator to alloc frame for new page table(first/second) + info!("ActivePageTable: calling RecursivePageTable::map_to, va={:x}, pa={:x}, flags={:?}", page.start_address().as_usize(), frame.start_address().as_usize(), flags); self.0.map_to(page, frame, flags, &mut FrameAllocatorForRiscv) .unwrap().flush(); self.get_entry(addr).expect("fail to get entry") @@ -174,14 +177,19 @@ const ROOT_PAGE_TABLE: *mut RvPageTable = (((RECURSIVE_INDEX << 10) | (RECURSIVE_INDEX + 1)) << 12) as *mut RvPageTable; #[cfg(target_arch = "riscv64")] const ROOT_PAGE_TABLE: *mut RvPageTable = - ((RECURSIVE_INDEX << 12 << 9 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; + ((0xFFFF_0000_0000_0000) | + (RECURSIVE_INDEX << 12 << 9 << 9 << 9) | + (RECURSIVE_INDEX << 12 << 9 << 9) | + (RECURSIVE_INDEX << 12 << 9) | + ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; impl ActivePageTable { pub unsafe fn new() -> Self { - ActivePageTable(RecursivePageTable::new(&mut *ROOT_PAGE_TABLE).unwrap()) + // TODO: delete debug code + let rv = ActivePageTable(RecursivePageTable::new(&mut *ROOT_PAGE_TABLE).unwrap()); + info!("ROOT_PAGE_TABLE: {:x}, ActivePageTable::new.0.pagetable: {:x}", + ROOT_PAGE_TABLE as usize, unsafe { rv.0.root_table as *const _ as usize }); + rv } /* @@ -194,15 +202,37 @@ impl ActivePageTable { #[cfg(target_arch = "riscv64")] fn with_temporary_map(&mut self, frame: &Frame, f: impl FnOnce(&mut ActivePageTable, &mut RvPageTable)) { // Create a temporary page - let page = Page::of_addr(VirtAddr::new(0xffffffffcafebabe)); + info!("enter with_temporary_map"); + let page = Page::of_addr(VirtAddr::new(0xffffdeadcafebabe)); + + info!("translate page begin, self at {:x}, page: {:x} ({:o}, {:o}, {:o}, {:o})", + (self.0.root_table as *const _ as usize), + page.start_address().as_usize(), + page.p4_index(), + page.p3_index(), + page.p2_index(), + page.p1_index() ); + info!("self info: recursive_index={:x}", + self.0.recursive_index); + info!("root_table[recursive_index]={:?}", + self.0.root_table[self.0.recursive_index]); + info!("root_table[recursive_index+1]={:?}", + self.0.root_table[self.0.recursive_index+1]); + assert!(self.0.translate_page(page).is_none(), "temporary page is already mapped"); + + info!("enter with_temporary_map check temporary mapped success"); // Map it to table self.map(page.start_address().as_usize(), frame.start_address().as_usize()); + // TODO: delete debug code + let t: usize = 0xffffdeadcafebabe; + info!("with_temporary_map: {:?}->{:?}, translate result {:?}", frame.start_address(), t, self.0.translate_page(page)); // Call f let table = unsafe { &mut *(page.start_address().as_usize() as *mut _) }; f(self, table); // Unmap the page - self.unmap(0xffffffffcafebabe); + self.unmap(0xffffdeadcafebabe); + info!("leaving with_temporary_map"); } #[cfg(target_arch = "riscv32")] @@ -302,12 +332,19 @@ impl InactivePageTable for InactivePageTable0 { * the inactive page table */ fn new_bare() -> Self { + info!("InactivePageTable0:new bare begin"); let frame = Self::alloc_frame().map(|target| Frame::of_addr(PhysAddr::new(target))) .expect("failed to allocate frame"); - active_table().with_temporary_map(&frame, |_, table: &mut RvPageTable| { + info!("new bare before with_temporary_map"); + // TODO: delete debug code + let mut at = active_table(); + info!("got active table"); + at.with_temporary_map(&frame, |_, table: &mut RvPageTable| { + info!("enter closure of with_temporary_map"); table.zero(); table.set_recursive(RECURSIVE_INDEX, frame.clone()); }); + info!("new bare after with_temporary_map"); InactivePageTable0 { root_frame: frame } } diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 772c586a..04ab9775 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -23,8 +23,12 @@ pub type MemorySet = ucore_memory::no_mmu::MemorySet; #[cfg(target_arch = "x86_64")] pub type FrameAlloc = BitAlloc64K; -// RISCV only have 8M memory -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +// RISCV32 has 8M memory +#[cfg(target_arch = "riscv32")] +pub type FrameAlloc = BitAlloc4K; + +// RISCV64 has 8M memory. +#[cfg(target_arch = "riscv64")] pub type FrameAlloc = BitAlloc4K; // Raspberry Pi 3 has 1G memory @@ -64,10 +68,17 @@ pub fn active_table_swap() -> MutexGuard<'static, SwapExt Option { // get the real address of the alloc frame - let ret = FRAME_ALLOCATOR.lock().alloc().map(|id| id * PAGE_SIZE + MEMORY_OFFSET); + // TODO: delete debug code + info!("alloc_frame"); + let mut ret = FRAME_ALLOCATOR.lock(); + info!("alloc_frame _2"); + let ret = ret.alloc(); + info!("alloc_frame _3"); + let ret = ret.map(|id| id * PAGE_SIZE + MEMORY_OFFSET); trace!("Allocate frame: {:x?}", ret); + ret //do we need : unsafe { ACTIVE_TABLE_SWAP.force_unlock(); } ??? - Some(ret.unwrap_or_else(|| active_table_swap().swap_out_any::().ok().expect("fail to swap out page"))) + // Some(ret.unwrap_or_else(|| active_table_swap().swap_out_any::().ok().expect("fail to swap out page"))) } pub fn dealloc_frame(target: usize) { @@ -107,7 +118,7 @@ impl Drop for KernelStack { */ #[cfg(not(feature = "no_mmu"))] pub fn page_fault_handler(addr: usize) -> bool { - info!("start handling swap in/out page fault"); + info!("start handling swap in/out page fault, badva={:x}", addr); //unsafe { ACTIVE_TABLE_SWAP.force_unlock(); } /*LAB3 EXERCISE 1: YOUR STUDENT NUMBER