From 5ce7d0a9c04fc8dc919ea26d8b5fddeb44fdc04e Mon Sep 17 00:00:00 2001 From: WangRunji Date: Fri, 16 Nov 2018 01:22:47 +0800 Subject: [PATCH] use user shell by default. fix kernel shell removing user thread. --- crate/process/src/thread.rs | 11 ++++++++--- kernel/src/arch/riscv32/mod.rs | 2 +- kernel/src/arch/x86_64/mod.rs | 2 +- kernel/src/fs.rs | 16 +++++++++++++++- kernel/src/shell.rs | 17 +++++++++-------- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/crate/process/src/thread.rs b/crate/process/src/thread.rs index 7ffa0e6..e2735df 100644 --- a/crate/process/src/thread.rs +++ b/crate/process/src/thread.rs @@ -32,9 +32,7 @@ fn new_kernel_context(entry: extern fn(usize) -> !, arg: usize) -> Box /// Gets a handle to the thread that invokes it. pub fn current() -> Thread { - Thread { - pid: processor().pid(), - } + Thread { pid: processor().pid() } } /// Puts the current thread to sleep for the specified amount of time. @@ -162,6 +160,13 @@ impl JoinHandle { processor().yield_now(); } } + /// Force construct a JoinHandle struct + pub unsafe fn _of(pid: Pid) -> JoinHandle { + JoinHandle { + thread: Thread { pid }, + mark: PhantomData, + } + } } //pub struct LocalKey { diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 22c2bf0..ffdb088 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -27,7 +27,7 @@ pub extern fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! { timer::init(); ::process::init(); - ::thread::spawn(::shell::shell); + ::thread::spawn(::shell::run_user_shell); unsafe { cpu::start_others(hart_mask); } ::kmain(); diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 3f7fda5..5d03d9c 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -48,7 +48,7 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! { driver::init(); ::process::init(); - ::thread::spawn(::shell::shell); + ::thread::spawn(::shell::run_user_shell); AP_CAN_INIT.store(true, Ordering::Relaxed); diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index 8ea584f..b70e89b 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -1,5 +1,5 @@ use simple_filesystem::*; -use alloc::{boxed::Box, sync::Arc, string::String, collections::VecDeque}; +use alloc::{boxed::Box, sync::Arc, string::String, collections::VecDeque, vec::Vec}; #[cfg(target_arch = "x86_64")] use arch::driver::ide; use sync::Condvar; @@ -139,4 +139,18 @@ impl INode for Stdout { Ok(buf.len()) } impl_inode!(); +} + +pub trait INodeExt { + fn read_as_vec(&self) -> Result>; +} + +impl INodeExt for INode { + fn read_as_vec(&self) -> Result> { + let size = self.info()?.size; + let mut buf = Vec::with_capacity(size); + unsafe { buf.set_len(size); } + self.read_at(0, buf.as_mut_slice())?; + Ok(buf) + } } \ No newline at end of file diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index c227d9f..4f48732 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -2,17 +2,19 @@ use alloc::string::String; use alloc::vec::Vec; -use fs::ROOT_INODE; +use fs::{ROOT_INODE, INodeExt}; use process::*; +pub fn run_user_shell() { + let inode = ROOT_INODE.lookup("sh").unwrap(); + let data = inode.read_as_vec().unwrap(); + processor().manager().add(ContextImpl::new_user(data.as_slice(), "sh".split(' '))); +} pub fn shell() { let files = ROOT_INODE.list().unwrap(); println!("Available programs: {:?}", files); - const BUF_SIZE: usize = 0x40000; - let mut buf = Vec::with_capacity(BUF_SIZE); - unsafe { buf.set_len(BUF_SIZE); } loop { print!(">> "); let cmd = get_line(); @@ -21,10 +23,9 @@ pub fn shell() { } let name = cmd.split(' ').next().unwrap(); if let Ok(file) = ROOT_INODE.lookup(name) { - let len = file.read_at(0, &mut *buf).unwrap(); - let pid = processor().manager().add(ContextImpl::new_user(&buf[..len], cmd.split(' '))); - processor().manager().wait(thread::current().id(), pid); - processor().yield_now(); + let data = file.read_as_vec().unwrap(); + let pid = processor().manager().add(ContextImpl::new_user(data.as_slice(), cmd.split(' '))); + unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap(); } else { println!("Program not exist"); }