From 8ee3671269ccbebcc962ef61ec30c3dd525b6d93 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Mon, 7 Dec 2020 18:57:23 +0800 Subject: [PATCH] Split kernel/user trap handler && Fix user tests. --- os/build.rs | 1 + os/src/config.rs | 3 - os/src/loader.rs | 127 -------------------------------------- os/src/main.rs | 5 +- os/src/mm/memory_set.rs | 10 +-- os/src/mm/page_table.rs | 2 + os/src/task/mod.rs | 1 - os/src/task/task.rs | 1 - os/src/trap/context.rs | 6 +- os/src/trap/mod.rs | 20 +++++- user/src/bin/00power_3.rs | 10 +-- user/src/bin/01power_5.rs | 10 +-- user/src/bin/02power_7.rs | 10 +-- 13 files changed, 45 insertions(+), 161 deletions(-) diff --git a/os/build.rs b/os/build.rs index 4bf29e89..792fe3c4 100644 --- a/os/build.rs +++ b/os/build.rs @@ -3,6 +3,7 @@ use std::fs::{File, read_dir}; fn main() { println!("cargo:rerun-if-changed=../user/src/"); + println!("cargo:rerun-if-changed={}", TARGET_PATH); insert_app_data().unwrap(); } diff --git a/os/src/config.rs b/os/src/config.rs index b717d941..aac95791 100644 --- a/os/src/config.rs +++ b/os/src/config.rs @@ -1,8 +1,5 @@ pub const USER_STACK_SIZE: usize = 4096 * 2; pub const KERNEL_STACK_SIZE: usize = 4096 * 2; -pub const MAX_APP_NUM: usize = 4; -pub const APP_BASE_ADDRESS: usize = 0x80100000; -pub const APP_SIZE_LIMIT: usize = 0x20000; pub const KERNEL_HEAP_SIZE: usize = 0x30_0000; pub const MEMORY_END: usize = 0x80800000; pub const PAGE_SIZE: usize = 0x1000; diff --git a/os/src/loader.rs b/os/src/loader.rs index 7c23b5d9..6d284743 100644 --- a/os/src/loader.rs +++ b/os/src/loader.rs @@ -1,54 +1,3 @@ -use crate::trap::TrapContext; -use crate::task::TaskContext; -use crate::config::*; -use xmas_elf::ElfFile; - -/* -#[repr(align(4096))] -struct KernelStack { - data: [u8; KERNEL_STACK_SIZE], -} - -#[repr(align(4096))] -struct UserStack { - data: [u8; USER_STACK_SIZE], -} - -static KERNEL_STACK: [KernelStack; MAX_APP_NUM] = [ - KernelStack { data: [0; KERNEL_STACK_SIZE], }; - MAX_APP_NUM -]; - -static USER_STACK: [UserStack; MAX_APP_NUM] = [ - UserStack { data: [0; USER_STACK_SIZE], }; - MAX_APP_NUM -]; - -impl KernelStack { - fn get_sp(&self) -> usize { - self.data.as_ptr() as usize + KERNEL_STACK_SIZE - } - pub fn push_context(&self, trap_cx: TrapContext, task_cx: TaskContext) -> &'static mut TaskContext { - unsafe { - let trap_cx_ptr = (self.get_sp() - core::mem::size_of::()) as *mut TrapContext; - *trap_cx_ptr = trap_cx; - let task_cx_ptr = (trap_cx_ptr as usize - core::mem::size_of::()) as *mut TaskContext; - *task_cx_ptr = task_cx; - task_cx_ptr.as_mut().unwrap() - } - } -} - -impl UserStack { - fn get_sp(&self) -> usize { - self.data.as_ptr() as usize + USER_STACK_SIZE - } -} -*/ -fn get_base_i(app_id: usize) -> usize { - APP_BASE_ADDRESS + app_id * APP_SIZE_LIMIT -} - pub fn get_num_app() -> usize { extern "C" { fn _num_app(); } unsafe { (_num_app as usize as *const usize).read_volatile() } @@ -69,79 +18,3 @@ pub fn get_app_data(app_id: usize) -> &'static [u8] { ) } } - -/* -fn debug_elf(start_addr: usize, end_addr: usize) { - let data_array = unsafe { - core::slice::from_raw_parts(start_addr as *const u8, end_addr - start_addr) - }; - let elf = ElfFile::new(data_array).unwrap(); - let elf_header = elf.header; - let magic = elf_header.pt1.magic; - assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!"); - let ph_count = elf_header.pt2.ph_count(); - println!("ph_count = {}", ph_count); - for i in 0..ph_count { - let ph = elf.program_header(i).unwrap(); - if ph.get_type().unwrap() == xmas_elf::program::Type::Load { - println!( - "offset={:#x},va={:#x},pa={:#x},filesz={:#x},memsz={:#x},align={:#x},flag={:?}", - ph.offset(), - ph.virtual_addr(), - ph.physical_addr(), - ph.file_size(), - ph.mem_size(), - ph.align(), - ph.flags(), - ); - //println!("len={:?}", ph.get_data(&elf).unwrap()); - } - } -} - -pub fn load_apps() { - extern "C" { fn _num_app(); } - let num_app_ptr = _num_app as usize as *const usize; - let num_app = get_num_app(); - let app_start = unsafe { - core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) - }; - println!("num_app = {}", num_app); - for i in 0..num_app { - println!( - "app_{} [{:#x},{:#x}) size={:#x}", - i, - app_start[i], - app_start[i + 1], - app_start[i + 1] - app_start[i] - ); - debug_elf(app_start[i], app_start[i + 1]); - } - loop {} - // clear i-cache first - unsafe { llvm_asm!("fence.i" :::: "volatile"); } - // load apps - for i in 0..num_app { - let base_i = get_base_i(i); - // clear region - (base_i..base_i + APP_SIZE_LIMIT).for_each(|addr| unsafe { - (addr as *mut u8).write_volatile(0) - }); - // load app from data section to memory - let src = unsafe { - core::slice::from_raw_parts(app_start[i] as *const u8, app_start[i + 1] - app_start[i]) - }; - let dst = unsafe { - core::slice::from_raw_parts_mut(base_i as *mut u8, src.len()) - }; - dst.copy_from_slice(src); - } -} - -pub fn init_app_cx(app_id: usize) -> &'static TaskContext { - KERNEL_STACK[app_id].push_context( - TrapContext::app_init_context(get_base_i(app_id), USER_STACK[app_id].get_sp()), - TaskContext::goto_restore(), - ) -} -*/ \ No newline at end of file diff --git a/os/src/main.rs b/os/src/main.rs index 12173b14..145f50a1 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -44,10 +44,9 @@ pub fn rust_main() -> ! { println!("[kernel] back to world!"); mm::remap_test(); trap::init(); - //loader::load_apps(); //trap::enable_interrupt(); - //trap::enable_timer_interrupt(); - //timer::set_next_trigger(); + trap::enable_timer_interrupt(); + timer::set_next_trigger(); task::run_first_task(); panic!("Unreachable in rust_main!"); } \ No newline at end of file diff --git a/os/src/mm/memory_set.rs b/os/src/mm/memory_set.rs index 580451b2..15b36f79 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -2,7 +2,6 @@ use super::{PageTable, PageTableEntry, PTEFlags}; use super::{VirtPageNum, VirtAddr, PhysPageNum, PhysAddr}; use super::{FrameTracker, frame_alloc}; use super::{VPNRange, StepByOne}; -use core::ops::Range; use alloc::collections::BTreeMap; use alloc::vec::Vec; use riscv::register::satp; @@ -16,7 +15,6 @@ use crate::config::{ TRAP_CONTEXT, USER_STACK_SIZE }; -use xmas_elf::ElfFile; extern "C" { fn stext(); @@ -169,7 +167,7 @@ impl MemorySet { } // map user stack with U flags //println!("mapping user stack!"); - let mut max_end_va: VirtAddr = max_end_vpn.into(); + let max_end_va: VirtAddr = max_end_vpn.into(); let mut user_stack_bottom: usize = max_end_va.into(); // guard page user_stack_bottom += PAGE_SIZE; @@ -227,8 +225,7 @@ impl MapArea { } } pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) { - let mut pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap(); - let mut ppn = PhysPageNum(0); + let ppn: PhysPageNum; match self.map_type { MapType::Identical => { ppn = PhysPageNum(vpn.0); @@ -239,8 +236,10 @@ impl MapArea { self.data_frames.insert(vpn, frame); } } + let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap(); page_table.map(vpn, ppn, pte_flags); } + #[allow(unused)] pub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) { match self.map_type { MapType::Framed => { @@ -255,6 +254,7 @@ impl MapArea { self.map_one(page_table, vpn); } } + #[allow(unused)] pub fn unmap(&mut self, page_table: &mut PageTable) { for vpn in self.vpn_range { self.unmap_one(page_table, vpn); diff --git a/os/src/mm/page_table.rs b/os/src/mm/page_table.rs index 86ba8d8d..be3eb378 100644 --- a/os/src/mm/page_table.rs +++ b/os/src/mm/page_table.rs @@ -113,12 +113,14 @@ impl PageTable { } result } + #[allow(unused)] pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) { //println!("mapping {:?} {:?}", vpn, ppn); let pte = self.find_pte_create(vpn).unwrap(); assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn); *pte = PageTableEntry::new(ppn, flags | PTEFlags::V); } + #[allow(unused)] pub fn unmap(&mut self, vpn: VirtPageNum) { let pte = self.find_pte_create(vpn).unwrap(); assert!(pte.is_valid(), "vpn {:?} is invalid before unmapping", vpn); diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index f40fa368..6d51f10a 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -2,7 +2,6 @@ mod context; mod switch; mod task; -use crate::config::MAX_APP_NUM; use crate::loader::{get_num_app, get_app_data}; use crate::trap::TrapContext; use core::cell::RefCell; diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 0183fd0c..071a814d 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -71,7 +71,6 @@ impl TaskControlBlock { #[derive(Copy, Clone, PartialEq)] pub enum TaskStatus { - UnInit, Ready, Running, Exited, diff --git a/os/src/trap/context.rs b/os/src/trap/context.rs index 61660aac..ce076fcc 100644 --- a/os/src/trap/context.rs +++ b/os/src/trap/context.rs @@ -21,11 +21,7 @@ impl TrapContext { ) -> Self { let mut sstatus = sstatus::read(); sstatus.set_spp(SPP::User); - let mut temp_sstatus: usize; - unsafe { - llvm_asm!("csrr $0, sstatus" : "=r"(temp_sstatus) ::: "volatile"); - } - println!("sstatus={:#x}", temp_sstatus); + sstatus.set_spie(true); let mut cx = Self { x: [0; 32], sstatus, diff --git a/os/src/trap/mod.rs b/os/src/trap/mod.rs index f11106d9..839ed049 100644 --- a/os/src/trap/mod.rs +++ b/os/src/trap/mod.rs @@ -26,11 +26,22 @@ use crate::config::{TRAP_CONTEXT, TRAMPOLINE}; global_asm!(include_str!("trap.S")); pub fn init() { + set_kernel_trap_entry(); +} + +fn set_kernel_trap_entry() { unsafe { - stvec::write(TRAMPOLINE, TrapMode::Direct); + stvec::write(trap_from_kernel as usize, TrapMode::Direct); } } +fn set_user_trap_entry() { + unsafe { + stvec::write(TRAMPOLINE as usize, TrapMode::Direct); + } +} + +#[allow(unused)] pub fn enable_interrupt() { unsafe { sstatus::set_sie(); } } @@ -42,6 +53,7 @@ pub fn enable_timer_interrupt() { #[no_mangle] pub fn trap_handler() -> ! { //println!("into trap_handler!"); + set_kernel_trap_entry(); let cx = current_trap_cx(); let scause = scause::read(); let stval = stval::read(); @@ -73,6 +85,7 @@ pub fn trap_handler() -> ! { #[no_mangle] pub fn trap_return() -> ! { + set_user_trap_entry(); //println!("into trap_return"); let trap_cx_ptr = TRAP_CONTEXT; let user_satp = current_user_token(); @@ -90,4 +103,9 @@ pub fn trap_return() -> ! { panic!("Unreachable in back_to_user!"); } +#[no_mangle] +pub fn trap_from_kernel() -> ! { + panic!("a trap from kernel!"); +} + pub use context::{TrapContext}; diff --git a/user/src/bin/00power_3.rs b/user/src/bin/00power_3.rs index 101660a2..532829da 100644 --- a/user/src/bin/00power_3.rs +++ b/user/src/bin/00power_3.rs @@ -6,24 +6,24 @@ extern crate user_lib; const LEN: usize = 100; -static mut s: [u64; LEN] = [0u64; LEN]; +static mut S: [u64; LEN] = [0u64; LEN]; #[no_mangle] unsafe fn main() -> i32 { let p = 3u64; let m = 998244353u64; - let iter: usize = 100000; + let iter: usize = 300000; let mut cur = 0usize; - s[cur] = 1; + S[cur] = 1; for i in 1..=iter { let next = if cur + 1 == LEN { 0 } else { cur + 1 }; - s[next] = s[cur] * p % m; + S[next] = S[cur] * p % m; cur = next; if i % 10000 == 0 { println!("power_3 [{}/{}]", i, iter); } } - println!("{}^{} = {}", p, iter, s[cur]); + println!("{}^{} = {}(mod {})", p, iter, S[cur], m); println!("Test power_3 OK!"); 0 } \ No newline at end of file diff --git a/user/src/bin/01power_5.rs b/user/src/bin/01power_5.rs index de67dc1d..f23e3b84 100644 --- a/user/src/bin/01power_5.rs +++ b/user/src/bin/01power_5.rs @@ -6,24 +6,24 @@ extern crate user_lib; const LEN: usize = 100; -static mut s: [u64; LEN] = [0u64; LEN]; +static mut S: [u64; LEN] = [0u64; LEN]; #[no_mangle] unsafe fn main() -> i32 { let p = 5u64; let m = 998244353u64; - let iter: usize = 70000; + let iter: usize = 210000; let mut cur = 0usize; - s[cur] = 1; + S[cur] = 1; for i in 1..=iter { let next = if cur + 1 == LEN { 0 } else { cur + 1 }; - s[next] = s[cur] * p % m; + S[next] = S[cur] * p % m; cur = next; if i % 10000 == 0 { println!("power_5 [{}/{}]", i, iter); } } - println!("{}^{} = {}", p, iter, s[cur]); + println!("{}^{} = {}(mod {})", p, iter, S[cur], m); println!("Test power_5 OK!"); 0 } diff --git a/user/src/bin/02power_7.rs b/user/src/bin/02power_7.rs index 9d3b6efa..35bada18 100644 --- a/user/src/bin/02power_7.rs +++ b/user/src/bin/02power_7.rs @@ -6,24 +6,24 @@ extern crate user_lib; const LEN: usize = 100; -static mut s: [u64; LEN] = [0u64; LEN]; +static mut S: [u64; LEN] = [0u64; LEN]; #[no_mangle] unsafe fn main() -> i32 { let p = 7u64; let m = 998244353u64; - let iter: usize = 80000; + let iter: usize = 240000; let mut cur = 0usize; - s[cur] = 1; + S[cur] = 1; for i in 1..=iter { let next = if cur + 1 == LEN { 0 } else { cur + 1 }; - s[next] = s[cur] * p % m; + S[next] = S[cur] * p % m; cur = next; if i % 10000 == 0 { println!("power_7 [{}/{}]", i, iter); } } - println!("{}^{} = {}", p, iter, s[cur]); + println!("{}^{} = {}(mod {})", p, iter, S[cur], m); println!("Test power_7 OK!"); 0 }