impl file syscalls, without test

master
WangRunji 6 years ago
parent 200a574a1f
commit e27aea47e1

2
kernel/Cargo.lock generated

@ -209,7 +209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "simple-filesystem" name = "simple-filesystem"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/wangrunji0408/SimpleFileSystem-Rust?branch=multi-thread#d75aab77d685791d6d919f901cc8ec8f29075ff6" source = "git+https://github.com/wangrunji0408/SimpleFileSystem-Rust?branch=multi-thread#80d72a9853aa8d64c3dc5f8117fc78a50b6f6ca3"
dependencies = [ dependencies = [
"bit-vec 0.5.0 (git+https://github.com/AltSysrq/bit-vec.git)", "bit-vec 0.5.0 (git+https://github.com/AltSysrq/bit-vec.git)",
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",

@ -1,7 +1,7 @@
use simple_filesystem::*; use simple_filesystem::*;
use alloc::{boxed::Box, sync::Arc}; use alloc::{boxed::Box, sync::Arc};
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use arch::driver::ide::IDE; use arch::driver::ide;
use spin::Mutex; use spin::Mutex;
// Hard link user program // Hard link user program
@ -17,7 +17,7 @@ _user_img_end:
"#); "#);
lazy_static! { lazy_static! {
static ref ROOT_INODE: Arc<INode> = { pub static ref ROOT_INODE: Arc<INode> = {
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
let device = { let device = {
extern { extern {
@ -27,7 +27,7 @@ lazy_static! {
Box::new(unsafe { MemBuf::new(_user_img_start, _user_img_end) }) Box::new(unsafe { MemBuf::new(_user_img_start, _user_img_end) })
}; };
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
let device = Box::new(IDE::new(1)); let device = Box::new(ide::IDE::new(1));
let sfs = SimpleFileSystem::open(device).expect("failed to open SFS"); let sfs = SimpleFileSystem::open(device).expect("failed to open SFS");
sfs.root_inode() sfs.root_inode()
@ -88,7 +88,7 @@ impl Device for MemBuf {
use core::slice; use core::slice;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
impl BlockedDevice for IDE { impl BlockedDevice for ide::IDE {
const BLOCK_SIZE_LOG2: u8 = 9; const BLOCK_SIZE_LOG2: u8 = 9;
fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool { fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool {
assert!(buf.len() >= ide::BLOCK_SIZE); assert!(buf.len() >= ide::BLOCK_SIZE);

@ -3,12 +3,14 @@ use memory::{MemoryArea, MemoryAttr, MemorySet, KernelStack};
use xmas_elf::{ElfFile, header, program::{Flags, ProgramHeader, Type}}; use xmas_elf::{ElfFile, header, program::{Flags, ProgramHeader, Type}};
use core::fmt::{Debug, Error, Formatter}; use core::fmt::{Debug, Error, Formatter};
use ucore_process::Context; use ucore_process::Context;
use alloc::boxed::Box; use simple_filesystem::file::File;
use alloc::{boxed::Box, collections::BTreeMap};
pub struct ContextImpl { pub struct ContextImpl {
arch: ArchContext, arch: ArchContext,
memory_set: MemorySet, memory_set: MemorySet,
kstack: KernelStack, kstack: KernelStack,
pub files: BTreeMap<usize, Box<File>>,
} }
impl Context for ContextImpl { impl Context for ContextImpl {
@ -25,6 +27,7 @@ impl ContextImpl {
arch: ArchContext::null(), arch: ArchContext::null(),
memory_set: MemorySet::new(), memory_set: MemorySet::new(),
kstack: KernelStack::new(), kstack: KernelStack::new(),
files: BTreeMap::default(),
}) })
} }
@ -35,6 +38,7 @@ impl ContextImpl {
arch: unsafe { ArchContext::new_kernel_thread(entry, arg, kstack.top(), memory_set.token()) }, arch: unsafe { ArchContext::new_kernel_thread(entry, arg, kstack.top(), memory_set.token()) },
memory_set, memory_set,
kstack, kstack,
files: BTreeMap::default(),
}) })
} }
@ -95,6 +99,7 @@ impl ContextImpl {
}, },
memory_set, memory_set,
kstack, kstack,
files: BTreeMap::default(),
}) })
} }
@ -124,6 +129,7 @@ impl ContextImpl {
arch: unsafe { ArchContext::new_fork(tf, kstack.top(), memory_set.token()) }, arch: unsafe { ArchContext::new_fork(tf, kstack.top(), memory_set.token()) },
memory_set, memory_set,
kstack, kstack,
files: BTreeMap::default(),
}) })
} }
} }

@ -1,4 +1,4 @@
//! 系统调用解析执行模块 //! System call
#![allow(unused)] #![allow(unused)]
@ -6,25 +6,45 @@ use arch::interrupt::TrapFrame;
use process::*; use process::*;
use thread; use thread;
use util; use util;
use simple_filesystem::{INode, file::File};
use core::{slice, str};
use alloc::boxed::Box;
/// 系统调用入口点 /// System call dispatcher
///
/// 当发生系统调用中断时,中断服务例程将控制权转移到这里。
pub fn syscall(id: usize, args: [usize; 6], tf: &TrapFrame) -> i32 { pub fn syscall(id: usize, args: [usize; 6], tf: &TrapFrame) -> i32 {
match id { match id {
SYS_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), // file
SYS_OPEN => sys_open(args[0] as *const u8, args[1]), 100 => sys_open(args[0] as *const u8, args[1]),
SYS_CLOSE => sys_close(args[0]), 101 => sys_close(args[0]),
SYS_WAIT => sys_wait(args[0], args[1] as *mut i32), 102 => sys_read(args[0], args[1] as *mut u8, args[2]),
SYS_FORK => sys_fork(tf), 103 => sys_write(args[0], args[1] as *const u8, args[2]),
SYS_KILL => sys_kill(args[0]), 030 => sys_putc(args[0] as u8 as char),
SYS_EXIT => sys_exit(args[0]), // 104 => sys_seek(),
SYS_YIELD => sys_yield(), // 110 => sys_fstat(),
SYS_GETPID => sys_getpid(), // 111 => sys_fsync(),
SYS_SLEEP => sys_sleep(args[0]), // 121 => sys_getcwd(),
SYS_GETTIME => sys_get_time(), // 128 => sys_getdirentry(),
SYS_LAB6_SET_PRIORITY => sys_lab6_set_priority(args[0]), // 128 => sys_dup(),
SYS_PUTC => sys_putc(args[0] as u8 as char),
// process
001 => sys_exit(args[0]),
002 => sys_fork(tf),
003 => sys_wait(args[0], args[1] as *mut i32),
// 004 => sys_exec(),
// 005 => sys_clone(),
010 => sys_yield(),
011 => sys_sleep(args[0]),
012 => sys_kill(args[0]),
017 => sys_get_time(),
018 => sys_getpid(),
255 => sys_lab6_set_priority(args[0]),
// memory
// 020 => sys_mmap(),
// 021 => sys_munmap(),
// 022 => sys_shmem(),
// 031 => sys_pgdir(),
_ => { _ => {
error!("unknown syscall id: {:#x?}, args: {:x?}", id, args); error!("unknown syscall id: {:#x?}, args: {:x?}", id, args);
::trap::error(tf); ::trap::error(tf);
@ -32,28 +52,73 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &TrapFrame) -> i32 {
} }
} }
fn sys_read(fd: usize, base: *mut u8, len: usize) -> i32 {
info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
let slice = unsafe { slice::from_raw_parts_mut(base, len) };
match fd {
0 => unimplemented!(),
1 | 2 => return -1,
_ => {
let mut file = process().files.get_mut(&fd);
if file.is_none() {
return -1;
}
let file = file.as_mut().unwrap();
file.read(slice).unwrap();
}
}
0
}
fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 { fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 {
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len); info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
use core::slice;
use core::str;
let slice = unsafe { slice::from_raw_parts(base, len) }; let slice = unsafe { slice::from_raw_parts(base, len) };
print!("{}", str::from_utf8(slice).unwrap()); match fd {
0 => return -1,
1 | 2 => print!("{}", str::from_utf8(slice).unwrap()),
_ => {
let mut file = process().files.get_mut(&fd);
if file.is_none() {
return -1;
}
let file = file.as_mut().unwrap();
file.write(slice).unwrap();
}
}
0 0
} }
fn sys_open(path: *const u8, flags: usize) -> i32 { fn sys_open(path: *const u8, flags: usize) -> i32 {
let path = unsafe { util::from_cstr(path) }; let path = unsafe { util::from_cstr(path) };
let flags = VfsFlags::from_ucore_flags(flags);
info!("open: path: {:?}, flags: {:?}", path, flags); info!("open: path: {:?}, flags: {:?}", path, flags);
match path { match path {
"stdin:" => 0, "stdin:" => return 0,
"stdout:" => 1, "stdout:" => return 1,
_ => -1, "stderr:" => return 2,
_ => {}
}
let inode = ::fs::ROOT_INODE.lookup(path);
if inode.is_err() {
return -1;
} }
let inode = inode.unwrap();
let files = &mut process().files;
let fd = (3..).find(|i| !files.contains_key(i)).unwrap();
let file = File::new(inode, flags.contains(VfsFlags::READABLE), flags.contains(VfsFlags::WRITABLE));
files.insert(fd, Box::new(file));
fd as i32
} }
fn sys_close(fd: usize) -> i32 { fn sys_close(fd: usize) -> i32 {
info!("close: fd: {:?}", fd); info!("close: fd: {:?}", fd);
0 if fd < 3 {
return 0;
}
match process().files.remove(&fd) {
Some(_) => 0,
None => -1,
}
} }
/// Fork the current process. Return the child's PID. /// Fork the current process. Return the child's PID.
@ -151,29 +216,25 @@ fn sys_putc(c: char) -> i32 {
0 0
} }
const SYS_EXIT: usize = 1; bitflags! {
const SYS_FORK: usize = 2; struct VfsFlags: usize {
const SYS_WAIT: usize = 3; // WARNING: different from origin uCore
const SYS_EXEC: usize = 4; const READABLE = 1 << 0;
const SYS_CLONE: usize = 5; const WRITABLE = 1 << 1;
const SYS_YIELD: usize = 10; /// create file if it does not exist
const SYS_SLEEP: usize = 11; const CREATE = 1 << 2;
const SYS_KILL: usize = 12; /// error if O_CREAT and the file exists
const SYS_GETTIME: usize = 17; const EXCLUSIVE = 1 << 3;
const SYS_GETPID: usize = 18; /// truncate file upon open
const SYS_MMAP: usize = 20; const TRUNCATE = 1 << 4;
const SYS_MUNMAP: usize = 21; /// append on each write
const SYS_SHMEM: usize = 22; const APPEND = 1 << 5;
const SYS_PUTC: usize = 30; }
const SYS_PGDIR: usize = 31; }
const SYS_OPEN: usize = 100;
const SYS_CLOSE: usize = 101; impl VfsFlags {
const SYS_READ: usize = 102; fn from_ucore_flags(f: usize) -> Self {
const SYS_WRITE: usize = 103; assert_ne!(f & 0b11, 0b11);
const SYS_SEEK: usize = 104; Self::from_bits_truncate(f + 1)
const SYS_FSTAT: usize = 110; }
const SYS_FSYNC: usize = 111; }
const SYS_GETCWD: usize = 121;
const SYS_GETDIRENTRY: usize = 128;
const SYS_DUP: usize = 130;
const SYS_LAB6_SET_PRIORITY: usize = 255;

Loading…
Cancel
Save