1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-27 02:03:29 +04:00
rCore/src/syscall.rs

212 lines
6.2 KiB
Rust
Raw Normal View History

2018-05-21 12:30:30 +04:00
//! 系统调用解析执行模块
2018-05-12 23:41:41 +04:00
use arch::interrupt::TrapFrame;
2018-05-21 12:30:30 +04:00
use process::*;
use util;
2018-05-12 23:41:41 +04:00
2018-05-21 12:30:30 +04:00
/// 系统调用入口点
///
/// 当发生系统调用中断时,中断服务例程将控制权转移到这里。
/// 它从中断帧中提取参数,根据系统调用号分发执行具体操作。
/// 它同时支持 xv6的64位程序 和 uCore的32位程序。
2018-05-20 15:15:01 +04:00
pub fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 {
2018-05-17 17:06:13 +04:00
let id = match is32 {
2018-05-20 15:15:01 +04:00
false => Syscall::Xv6(tf.rax),
true => Syscall::Ucore(tf.rax),
2018-05-17 17:06:13 +04:00
};
let args = match is32 {
// For ucore x86
2018-05-20 15:15:01 +04:00
true => [tf.rdx, tf.rcx, tf.rbx, tf.rdi, tf.rsi, 0],
2018-05-17 17:06:13 +04:00
// For xv6 x86_64
2018-05-20 15:15:01 +04:00
false => [tf.rdi, tf.rsi, tf.rdx, tf.rcx, tf.r8, tf.r9],
2018-05-17 17:06:13 +04:00
};
2018-05-12 23:41:41 +04:00
match id {
2018-05-17 18:15:26 +04:00
Syscall::Xv6(SYS_WRITE) | Syscall::Ucore(UCORE_SYS_WRITE) =>
2018-05-21 12:30:30 +04:00
sys_write(args[0], args[1] as *const u8, args[2]),
2018-05-17 18:15:26 +04:00
Syscall::Xv6(SYS_OPEN) | Syscall::Ucore(UCORE_SYS_OPEN) =>
2018-05-21 12:30:30 +04:00
sys_open(args[0] as *const u8, args[1]),
2018-05-17 18:15:26 +04:00
Syscall::Xv6(SYS_CLOSE) | Syscall::Ucore(UCORE_SYS_CLOSE) =>
2018-05-21 12:30:30 +04:00
sys_close(args[0]),
2018-05-19 12:32:18 +04:00
Syscall::Xv6(SYS_WAIT) | Syscall::Ucore(UCORE_SYS_WAIT) =>
2018-05-21 12:30:30 +04:00
sys_wait(rsp, args[0], args[1] as *mut i32),
2018-05-17 18:15:26 +04:00
Syscall::Xv6(SYS_FORK) | Syscall::Ucore(UCORE_SYS_FORK) =>
2018-05-21 12:30:30 +04:00
sys_fork(tf),
2018-05-17 18:15:26 +04:00
Syscall::Xv6(SYS_KILL) | Syscall::Ucore(UCORE_SYS_KILL) =>
2018-05-21 12:30:30 +04:00
sys_kill(args[0]),
2018-05-17 18:15:26 +04:00
Syscall::Xv6(SYS_EXIT) | Syscall::Ucore(UCORE_SYS_EXIT) =>
2018-05-21 12:30:30 +04:00
sys_exit(rsp, args[0]),
2018-05-20 13:14:05 +04:00
Syscall::Ucore(UCORE_SYS_YIELD) =>
2018-05-21 12:30:30 +04:00
sys_yield(rsp),
2018-05-17 18:15:26 +04:00
Syscall::Ucore(UCORE_SYS_GETPID) =>
2018-05-21 12:30:30 +04:00
sys_getpid(),
2018-05-19 20:22:52 +04:00
Syscall::Ucore(UCORE_SYS_SLEEP) =>
2018-05-21 12:30:30 +04:00
sys_sleep(rsp, args[0]),
2018-05-19 20:22:52 +04:00
Syscall::Ucore(UCORE_SYS_GETTIME) =>
2018-05-21 12:30:30 +04:00
sys_get_time(),
2018-05-17 18:15:26 +04:00
Syscall::Ucore(UCORE_SYS_PUTC) =>
{
print!("{}", args[0] as u8 as char);
0
2018-05-19 20:22:52 +04:00
}
2018-05-12 23:41:41 +04:00
_ => {
2018-05-19 20:22:52 +04:00
error!("unknown syscall {:#x?}", id);
2018-05-12 23:41:41 +04:00
-1
2018-05-19 20:22:52 +04:00
}
2018-05-12 23:41:41 +04:00
}
}
2018-05-21 12:30:30 +04:00
fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 {
info!("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
}
fn sys_open(path: *const u8, flags: usize) -> i32 {
let path = unsafe { util::from_cstr(path) };
info!("open: path: {:?}, flags: {:?}", path, flags);
match path {
"stdin:" => 0,
"stdout:" => 1,
_ => -1,
}
}
fn sys_close(fd: usize) -> i32 {
info!("close: fd: {:?}", fd);
0
}
/// Fork the current process. Return the child's PID.
fn sys_fork(tf: &TrapFrame) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let mut mc = MC.try().unwrap().lock();
let new = processor.current().fork(tf, &mut mc);
let pid = processor.add(new);
info!("fork: {} -> {}", processor.current_pid(), pid);
pid as i32
}
/// Wait the process exit.
/// Return the PID. Store exit code to `code` if it's not null.
fn sys_wait(rsp: &mut usize, pid: usize, code: *mut i32) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let target = match pid {
0 => WaitTarget::AnyChild,
_ => WaitTarget::Proc(pid),
};
match processor.current_wait_for(target) {
WaitResult::Ok(pid, error_code) => {
if !code.is_null() {
unsafe { *code = error_code as i32 };
}
0 // pid as i32
},
WaitResult::Blocked => {
processor.schedule(rsp);
0 /* unused */
},
WaitResult::NotExist => -1,
}
}
fn sys_yield(rsp: &mut usize) -> i32 {
info!("yield:");
let mut processor = PROCESSOR.try().unwrap().lock();
processor.schedule(rsp);
0
}
/// Kill the process
fn sys_kill(pid: usize) -> i32 {
PROCESSOR.try().unwrap().lock().kill(pid);
0
}
/// Get the current process id
fn sys_getpid() -> i32 {
PROCESSOR.try().unwrap().lock().current_pid() as i32
}
/// Exit the current process
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
}
fn sys_sleep(rsp: &mut usize, time: usize) -> i32 {
info!("sleep: {} ticks", time);
let mut processor = PROCESSOR.try().unwrap().lock();
let pid = processor.current_pid();
processor.schedule(rsp);
processor.sleep(pid, time);
0
}
fn sys_get_time() -> i32 {
let processor = PROCESSOR.try().unwrap().lock();
processor.get_time() as i32
}
2018-05-17 18:15:26 +04:00
#[derive(Debug)]
enum Syscall {
Xv6(usize),
Ucore(usize),
}
2018-05-12 23:41:41 +04:00
const SYS_FORK: usize = 1;
const SYS_EXIT: usize = 2;
const SYS_WAIT: usize = 3;
const SYS_PIPE: usize = 4;
const SYS_READ: usize = 5;
const SYS_KILL: usize = 6;
const SYS_EXEC: usize = 7;
const SYS_FSTAT: usize = 8;
const SYS_CHDIR: usize = 9;
const SYS_DUP: usize = 10;
const SYS_GETPID: usize = 11;
const SYS_SBRK: usize = 12;
const SYS_SLEEP: usize = 13;
const SYS_UPTIME: usize = 14;
const SYS_OPEN: usize = 15;
const SYS_WRITE: usize = 16;
const SYS_MKNOD: usize = 17;
const SYS_UNLINK: usize = 18;
const SYS_LINK: usize = 19;
const SYS_MKDIR: usize = 20;
const SYS_CLOSE: usize = 21;
const SYS_CHMOD: usize = 22;
2018-05-17 17:06:13 +04:00
const UCORE_SYS_EXIT: usize = 1;
const UCORE_SYS_FORK: usize = 2;
const UCORE_SYS_WAIT: usize = 3;
const UCORE_SYS_EXEC: usize = 4;
const UCORE_SYS_CLONE: usize = 5;
const UCORE_SYS_YIELD: usize = 10;
const UCORE_SYS_SLEEP: usize = 11;
const UCORE_SYS_KILL: usize = 12;
const UCORE_SYS_GETTIME: usize = 17;
const UCORE_SYS_GETPID: usize = 18;
const UCORE_SYS_MMAP: usize = 20;
const UCORE_SYS_MUNMAP: usize = 21;
const UCORE_SYS_SHMEM: usize = 22;
const UCORE_SYS_PUTC: usize = 30;
const UCORE_SYS_PGDIR: usize = 31;
const UCORE_SYS_OPEN: usize = 100;
const UCORE_SYS_CLOSE: usize = 101;
const UCORE_SYS_READ: usize = 102;
const UCORE_SYS_WRITE: usize = 103;
const UCORE_SYS_SEEK: usize = 104;
const UCORE_SYS_FSTAT: usize = 110;
const UCORE_SYS_FSYNC: usize = 111;
const UCORE_SYS_GETCWD: usize = 121;
const UCORE_SYS_GETDIRENTRY: usize = 128;
const UCORE_SYS_DUP: usize = 130;