diff --git a/os/build.rs b/os/build.rs index 3794b21a..ba1ff3de 100644 --- a/os/build.rs +++ b/os/build.rs @@ -2,11 +2,11 @@ use std::io::{Result, Write}; use std::fs::{File, read_dir}; fn main() { - println!("cargo:rerun-if-changed=../user"); + println!("cargo:rerun-if-changed=../user/src/bin/"); insert_app_data().unwrap(); } -static TARGET_PATH: &'static str = "../user/target/riscv64gc-unknown-none-elf/release/"; +static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/"; fn insert_app_data() -> Result<()> { let mut f = File::create("src/link_app.S").unwrap(); diff --git a/os/src/batch.rs b/os/src/batch.rs index 567b4b30..9e6bc278 100644 --- a/os/src/batch.rs +++ b/os/src/batch.rs @@ -43,7 +43,7 @@ struct AppManager { } struct AppManagerInner { num_app: usize, - next_app: usize, + current_app: usize, app_start: [usize; MAX_APP_NUM + 1], } unsafe impl Sync for AppManager {} @@ -57,6 +57,10 @@ impl AppManagerInner { } unsafe fn load_app(&self, app_id: usize) { + if app_id >= self.num_app { + panic!("All applications completed!"); + } + println!("[kernel] Loading app_{}", app_id); // clear app area (APP_BASE_ADDRESS..APP_BASE_ADDRESS + APP_SIZE_LIMIT).for_each(|addr| { (addr as *mut u8).write_volatile(0); @@ -72,15 +76,10 @@ impl AppManagerInner { app_dst.copy_from_slice(app_src); } - pub fn run_next_app(&mut self) { - unsafe { self.load_app(self.next_app); } - self.next_app += 1; - extern "C" { fn __restore(cx: &mut TrapContext); } - unsafe { - __restore(KERNEL_STACK.push_context( - TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp()) - )); - } + pub fn get_current_app(&self) -> usize { self.current_app } + + pub fn move_to_next_app(&mut self) { + self.current_app += 1; } } @@ -94,10 +93,10 @@ lazy_static! { let app_start_raw: &[usize] = unsafe { core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) }; - &app_start[..=num_app].copy_from_slice(app_start_raw); + app_start[..=num_app].copy_from_slice(app_start_raw); AppManagerInner { num_app, - next_app: 0, + current_app: 0, app_start, } }), @@ -112,6 +111,17 @@ pub fn print_app_info() { APP_MANAGER.inner.borrow().print_app_info(); } -pub fn run_next_app() { - APP_MANAGER.inner.borrow_mut().run_next_app(); +pub fn run_next_app() -> ! { + let current_app = APP_MANAGER.inner.borrow().get_current_app(); + unsafe { + APP_MANAGER.inner.borrow().load_app(current_app); + } + APP_MANAGER.inner.borrow_mut().move_to_next_app(); + extern "C" { fn __restore(cx_addr: usize); } + unsafe { + __restore(KERNEL_STACK.push_context( + TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp()) + ) as *const _ as usize); + } + panic!("Unreachable in batch::run_current_app!"); } diff --git a/os/src/lang_items.rs b/os/src/lang_items.rs index 655f6c4f..3f5462ab 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -4,9 +4,9 @@ use crate::sbi::shutdown; #[panic_handler] fn panic(info: &PanicInfo) -> ! { if let Some(location) = info.location() { - println!("Panicked at {}:{} {}", location.file(), location.line(), info.message().unwrap()); + println!("[kernel] Panicked at {}:{} {}", location.file(), location.line(), info.message().unwrap()); } else { - println!("Panicked: {}", info.message().unwrap()); + println!("[kernel] Panicked: {}", info.message().unwrap()); } shutdown() } diff --git a/os/src/main.rs b/os/src/main.rs index 67b32312..8f8fdeb7 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -28,8 +28,8 @@ fn clear_bss() { #[no_mangle] pub fn rust_main() -> ! { clear_bss(); - println!("Hello, world!"); + println!("[kernel] Hello, world!"); + trap::init(); batch::init(); batch::run_next_app(); - panic!("Shutdown machine!"); } \ No newline at end of file diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs new file mode 100644 index 00000000..b8c46591 --- /dev/null +++ b/os/src/syscall/fs.rs @@ -0,0 +1,15 @@ +const FD_STDOUT: usize = 1; + +pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { + match fd { + FD_STDOUT => { + let slice = unsafe { core::slice::from_raw_parts(buf, len) }; + let str = core::str::from_utf8(slice).unwrap(); + print!("{}", str); + len as isize + }, + _ => { + panic!("Unsupported fd in sys_write!"); + } + } +} \ No newline at end of file diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 5a1a1246..51dea1e7 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -1,2 +1,17 @@ const SYSCALL_WRITE: usize = 64; +const SYSCALL_EXIT: usize = 93; + +mod fs; +mod process; + +use fs::*; +use process::*; + +pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + match syscall_id { + SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), + SYSCALL_EXIT => sys_exit(args[0] as i32), + _ => panic!("Unsupported syscall_id: {}", syscall_id), + } +} diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs new file mode 100644 index 00000000..ef56607a --- /dev/null +++ b/os/src/syscall/process.rs @@ -0,0 +1,6 @@ +use crate::batch::run_next_app; + +pub fn sys_exit(xstate: i32) -> ! { + println!("[kernel] Application exited with code {}", xstate); + run_next_app() +} \ No newline at end of file diff --git a/os/src/trap/context.rs b/os/src/trap/context.rs index b4245227..e2575de9 100644 --- a/os/src/trap/context.rs +++ b/os/src/trap/context.rs @@ -2,9 +2,9 @@ use riscv::register::sstatus::{Sstatus, self, SPP}; #[repr(C)] pub struct TrapContext { - x: [usize; 32], - sstatus: Sstatus, - sepc: usize, + pub x: [usize; 32], + pub sstatus: Sstatus, + pub sepc: usize, } impl TrapContext { diff --git a/os/src/trap/mod.rs b/os/src/trap/mod.rs index 2d7db829..25cd9405 100644 --- a/os/src/trap/mod.rs +++ b/os/src/trap/mod.rs @@ -10,6 +10,7 @@ use riscv::register::{ }, stval, }; +use crate::syscall::syscall; global_asm!(include_str!("trap.S")); @@ -23,10 +24,11 @@ pub fn init() { #[no_mangle] pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext { let scause = scause::read(); - let stval = stval::read(); + let _stval = stval::read(); match scause.cause() { Trap::Exception(Exception::UserEnvCall) => { - panic!("Triggered UserEnvCall!"); + cx.sepc += 4; + cx.x[10] = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]) as usize; } _ => { panic!("Unsupported trap!"); diff --git a/user/src/bin/power.rs b/user/src/bin/power.rs index cc9cb32d..86154c71 100644 --- a/user/src/bin/power.rs +++ b/user/src/bin/power.rs @@ -6,7 +6,7 @@ extern crate user_lib; const SIZE: usize = 10; const P: u32 = 3; -const STEP: usize = 10000000; +const STEP: usize = 100000; const MOD: u32 = 10007; #[no_mangle]