uCore `hello` is available!

master
WangRunji 7 years ago
parent 8c64b2abb2
commit 893658baf8

@ -58,7 +58,7 @@ static mut TSS_PTR: Unique<TaskStateSegment> = 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());

@ -75,7 +75,7 @@ use spin::Mutex;
// FIXME: Deadlock
//static TICK: Mutex<usize> = 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;
});

@ -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;

@ -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;

@ -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()
}

@ -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
}

@ -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
}

@ -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);
}
}

@ -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,22 +13,38 @@ 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]);
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;

Loading…
Cancel
Save