From 893658baf81a4a47077adad29f41dd52b5bb8e6c Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 17 May 2018 22:15:26 +0800 Subject: [PATCH] uCore `hello` is available! --- src/arch/x86_64/gdt.rs | 2 +- src/arch/x86_64/interrupt/handler.rs | 12 +++---- src/arch/x86_64/interrupt/template.rs | 6 ++-- src/consts.rs | 2 +- src/io/mod.rs | 26 ++++++++++++-- src/process/mod.rs | 23 +++++++++++- src/process/process.rs | 2 +- src/process/processor.rs | 20 +++++++++-- src/syscall.rs | 50 ++++++++++++++++----------- 9 files changed, 106 insertions(+), 37 deletions(-) diff --git a/src/arch/x86_64/gdt.rs b/src/arch/x86_64/gdt.rs index a3095ae..76292f3 100644 --- a/src/arch/x86_64/gdt.rs +++ b/src/arch/x86_64/gdt.rs @@ -58,7 +58,7 @@ static mut TSS_PTR: Unique = unsafe{ Unique::new_unchecked(0 a /// /// 每次进入用户态前,都要调用此函数,才能保证正确返回内核态 pub fn set_ring0_rsp(rsp: usize) { - debug!("gdt.set_ring0_rsp: {:#x}", rsp); +// debug!("gdt.set_ring0_rsp: {:#x}", rsp); unsafe { TSS_PTR.as_mut().privilege_stack_table[0] = VirtualAddress(rsp); // debug!("TSS:\n{:?}", TSS_PTR.as_ref()); diff --git a/src/arch/x86_64/interrupt/handler.rs b/src/arch/x86_64/interrupt/handler.rs index 2e3797d..bb280ea 100644 --- a/src/arch/x86_64/interrupt/handler.rs +++ b/src/arch/x86_64/interrupt/handler.rs @@ -75,7 +75,7 @@ use spin::Mutex; // FIXME: Deadlock //static TICK: Mutex = Mutex::new(0); -interrupt_switch!(timer, rsp, { +interrupt_switch!(timer, stack, rsp, { // let mut tick = TICK.lock(); // *tick += 1; // let tick = *tick; @@ -107,16 +107,16 @@ interrupt_stack_p!(to_kernel, stack, { stack.iret.ss = gdt::KDATA_SELECTOR.0 as usize; }); -interrupt_stack_p!(syscall, stack, { +interrupt_switch!(syscall, stack, rsp, { println!("\nInterupt: Syscall {:#x?}", stack.scratch.rax); use syscall::syscall; - let ret = syscall(stack, false); + let ret = syscall(stack, rsp, false); stack.scratch.rax = ret as usize; }); -interrupt_stack_p!(syscall32, stack, { - println!("\nInterupt: Syscall {:#x?}", stack.scratch.rax); +interrupt_switch!(syscall32, stack, rsp, { +// println!("\nInterupt: Syscall {:#x?}", stack.scratch.rax); use syscall::syscall; - let ret = syscall(stack, true); + let ret = syscall(stack, rsp, true); stack.scratch.rax = ret as usize; }); \ No newline at end of file diff --git a/src/arch/x86_64/interrupt/template.rs b/src/arch/x86_64/interrupt/template.rs index 873a995..33480b2 100644 --- a/src/arch/x86_64/interrupt/template.rs +++ b/src/arch/x86_64/interrupt/template.rs @@ -315,11 +315,11 @@ impl Debug for InterruptStackP { } macro_rules! interrupt_switch { - ($name:ident, $rsp: ident, $func:block) => { + ($name:ident, $stack: ident, $rsp: ident, $func:block) => { #[naked] pub unsafe extern fn $name () { #[inline(never)] - unsafe fn inner($rsp: &mut usize) { + unsafe fn inner($stack: &mut InterruptStackP, $rsp: &mut usize) { $func } @@ -333,7 +333,7 @@ macro_rules! interrupt_switch { asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); // Call inner rust function - inner(&mut rsp); + inner(&mut *(rsp as *mut InterruptStackP), &mut rsp); // Set return rsp if to user use arch::gdt; diff --git a/src/consts.rs b/src/consts.rs index a267e79..5567824 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -26,7 +26,7 @@ pub const MAX_CPU_NUM: usize = 8; pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET - 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 = 2 * 1024 * 1024; // 1 MB + pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024; // 8 MB /// Offset to kernel percpu variables //TODO: Use 64-bit fs offset to enable this pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_HEAP_OFFSET - PML4_SIZE; diff --git a/src/io/mod.rs b/src/io/mod.rs index 0ce8438..3944f05 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -49,10 +49,32 @@ pub fn debug(args: fmt::Arguments) { print_in_color(args, Color::LightRed); } -pub fn write(fd: usize, base: *const u8, len: usize) { - // debug!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len); +pub fn write(fd: usize, base: *const u8, len: usize) -> i32 { + debug!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len); use core::slice; use core::str; let slice = unsafe { slice::from_raw_parts(base, len) }; print!("{}", str::from_utf8(slice).unwrap()); + 0 +} + +pub fn open(path: *const u8, flags: usize) -> i32 { + let path = unsafe { from_cstr(path) }; + debug!("open: path: {:?}, flags: {:?}", path, flags); + match path { + "stdin:" => 0, + "stdout:" => 1, + _ => -1, + } +} + +pub fn close(fd: usize) -> i32 { + debug!("close: fd: {:?}", fd); + 0 +} + +pub unsafe fn from_cstr(s: *const u8) -> &'static str { + use core::{str, slice}; + let len = (0usize..).find(|&i| *s.offset(i as isize) == 0).unwrap(); + str::from_utf8(slice::from_raw_parts(s, len)).unwrap() } \ No newline at end of file diff --git a/src/process/mod.rs b/src/process/mod.rs index cea83b8..a838c6b 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -76,6 +76,27 @@ extern fn idle_thread() { } /// Fork the current process -pub fn fork(tf: &TrapFrame) { +pub fn sys_fork(tf: &TrapFrame) -> i32 { PROCESSOR.try().unwrap().lock().fork(tf); + 0 +} + +/// Kill the process +pub fn sys_kill(pid: usize) -> i32 { + PROCESSOR.try().unwrap().lock().kill(pid); + 0 +} + +/// Get the current process id +pub fn sys_getpid() -> i32 { + PROCESSOR.try().unwrap().lock().current().pid as i32 +} + +/// Exit the current process +pub fn sys_exit(rsp: &mut usize, error_code: usize) -> i32 { + let mut processor = PROCESSOR.try().unwrap().lock(); + let pid = processor.current().pid; + processor.schedule(rsp); + processor.exit(pid, error_code); + 0 } \ No newline at end of file diff --git a/src/process/process.rs b/src/process/process.rs index aba7267..03291ef 100644 --- a/src/process/process.rs +++ b/src/process/process.rs @@ -19,7 +19,7 @@ pub struct Process { pub type Pid = usize; -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq)] pub enum Status { Ready, Running, Sleeping(usize), Exited } diff --git a/src/process/processor.rs b/src/process/processor.rs index 8f29793..90cb017 100644 --- a/src/process/processor.rs +++ b/src/process/processor.rs @@ -43,7 +43,8 @@ impl Processor { fn find_next(&self) -> Pid { *self.procs.keys() - .find(|&&i| i > self.current_pid) + .find(|&&i| i > self.current_pid + && self.get(i).status != Status::Exited) .unwrap_or(self.procs.keys().nth(0).unwrap()) } @@ -76,8 +77,12 @@ impl Processor { debug!("Processor: switch from {} to {}\n rsp: {:#x} -> {:#x}", pid0, pid, rsp0, rsp); } + fn get(&self, pid: Pid) -> &Process { + self.procs.get(&pid).unwrap() + } + pub fn current(&self) -> &Process { - self.procs.get(&self.current_pid).unwrap() + self.get(self.current_pid) } /// Fork the current process @@ -85,4 +90,15 @@ impl Processor { let new = self.current().fork(tf, &mut self.mc.borrow_mut()); self.add(new); } + + pub fn kill(&mut self, pid: Pid) { + let process = self.procs.get_mut(&pid).unwrap(); + process.status = Status::Exited; + // TODO: Remove process from set + } + + pub fn exit(&mut self, pid: Pid, error_code: usize) { + debug!("Processor: {} exit, code: {}", pid, error_code); + self.kill(pid); + } } \ No newline at end of file diff --git a/src/syscall.rs b/src/syscall.rs index 45bd6be..8dc3354 100644 --- a/src/syscall.rs +++ b/src/syscall.rs @@ -2,16 +2,10 @@ use super::*; use process; use arch::interrupt::TrapFrame; -pub unsafe fn syscall(tf: &TrapFrame, is32: bool) -> i32 { +pub unsafe fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 { let id = match is32 { - false => tf.scratch.rax, - true => match tf.scratch.rax { - UCORE_SYS_OPEN => SYS_OPEN, - UCORE_SYS_CLOSE => SYS_CLOSE, - UCORE_SYS_WRITE => SYS_WRITE, - UCORE_SYS_READ => SYS_READ, - _ => 0, - } + false => Syscall::Xv6(tf.scratch.rax), + true => Syscall::Ucore(tf.scratch.rax), }; let args = match is32 { // For ucore x86 @@ -19,24 +13,40 @@ pub unsafe fn syscall(tf: &TrapFrame, is32: bool) -> i32 { // For xv6 x86_64 false => [tf.scratch.rdi, tf.scratch.rsi, tf.scratch.rdx, tf.scratch.rcx, tf.scratch.r8, tf.scratch.r9], }; - debug!("id: {:#x}, args: {:#x?}", id, args); match id { - SYS_FORK => { - process::fork(tf); - 0 - } - SYS_WRITE => { - io::write(args[0], args[1] as *const u8, args[2]); - 0 - } + Syscall::Xv6(SYS_WRITE) | Syscall::Ucore(UCORE_SYS_WRITE) => + io::write(args[0], args[1] as *const u8, args[2]), + Syscall::Xv6(SYS_OPEN) | Syscall::Ucore(UCORE_SYS_OPEN) => + io::open(args[0] as *const u8, args[1]), + Syscall::Xv6(SYS_CLOSE) | Syscall::Ucore(UCORE_SYS_CLOSE) => + io::close(args[0]), + Syscall::Xv6(SYS_FORK) | Syscall::Ucore(UCORE_SYS_FORK) => + process::sys_fork(tf), + Syscall::Xv6(SYS_KILL) | Syscall::Ucore(UCORE_SYS_KILL) => + process::sys_kill(args[0]), + Syscall::Xv6(SYS_EXIT) | Syscall::Ucore(UCORE_SYS_EXIT) => + process::sys_exit(rsp, args[0]), + Syscall::Ucore(UCORE_SYS_GETPID) => + process::sys_getpid(), + Syscall::Ucore(UCORE_SYS_PUTC) => + { + print!("{}", args[0] as u8 as char); + 0 + }, _ => { - debug!("unknown syscall {:#x}", id); + debug!("unknown syscall {:#x?}", id); -1 - } + }, } } +#[derive(Debug)] +enum Syscall { + Xv6(usize), + Ucore(usize), +} + const SYS_FORK: usize = 1; const SYS_EXIT: usize = 2; const SYS_WAIT: usize = 3;