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]]
name = "simple-filesystem"
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 = [
"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)",

@ -1,7 +1,7 @@
use simple_filesystem::*;
use alloc::{boxed::Box, sync::Arc};
#[cfg(target_arch = "x86_64")]
use arch::driver::ide::IDE;
use arch::driver::ide;
use spin::Mutex;
// Hard link user program
@ -17,7 +17,7 @@ _user_img_end:
"#);
lazy_static! {
static ref ROOT_INODE: Arc<INode> = {
pub static ref ROOT_INODE: Arc<INode> = {
#[cfg(target_arch = "riscv32")]
let device = {
extern {
@ -27,7 +27,7 @@ lazy_static! {
Box::new(unsafe { MemBuf::new(_user_img_start, _user_img_end) })
};
#[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");
sfs.root_inode()
@ -88,7 +88,7 @@ impl Device for MemBuf {
use core::slice;
#[cfg(target_arch = "x86_64")]
impl BlockedDevice for IDE {
impl BlockedDevice for ide::IDE {
const BLOCK_SIZE_LOG2: u8 = 9;
fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool {
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 core::fmt::{Debug, Error, Formatter};
use ucore_process::Context;
use alloc::boxed::Box;
use simple_filesystem::file::File;
use alloc::{boxed::Box, collections::BTreeMap};
pub struct ContextImpl {
arch: ArchContext,
memory_set: MemorySet,
kstack: KernelStack,
pub files: BTreeMap<usize, Box<File>>,
}
impl Context for ContextImpl {
@ -25,6 +27,7 @@ impl ContextImpl {
arch: ArchContext::null(),
memory_set: MemorySet::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()) },
memory_set,
kstack,
files: BTreeMap::default(),
})
}
@ -95,6 +99,7 @@ impl ContextImpl {
},
memory_set,
kstack,
files: BTreeMap::default(),
})
}
@ -124,6 +129,7 @@ impl ContextImpl {
arch: unsafe { ArchContext::new_fork(tf, kstack.top(), memory_set.token()) },
memory_set,
kstack,
files: BTreeMap::default(),
})
}
}

@ -1,4 +1,4 @@
//! 系统调用解析执行模块
//! System call
#![allow(unused)]
@ -6,25 +6,45 @@ use arch::interrupt::TrapFrame;
use process::*;
use thread;
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 {
match id {
SYS_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
SYS_OPEN => sys_open(args[0] as *const u8, args[1]),
SYS_CLOSE => sys_close(args[0]),
SYS_WAIT => sys_wait(args[0], args[1] as *mut i32),
SYS_FORK => sys_fork(tf),
SYS_KILL => sys_kill(args[0]),
SYS_EXIT => sys_exit(args[0]),
SYS_YIELD => sys_yield(),
SYS_GETPID => sys_getpid(),
SYS_SLEEP => sys_sleep(args[0]),
SYS_GETTIME => sys_get_time(),
SYS_LAB6_SET_PRIORITY => sys_lab6_set_priority(args[0]),
SYS_PUTC => sys_putc(args[0] as u8 as char),
// file
100 => sys_open(args[0] as *const u8, args[1]),
101 => sys_close(args[0]),
102 => sys_read(args[0], args[1] as *mut u8, args[2]),
103 => sys_write(args[0], args[1] as *const u8, args[2]),
030 => sys_putc(args[0] as u8 as char),
// 104 => sys_seek(),
// 110 => sys_fstat(),
// 111 => sys_fsync(),
// 121 => sys_getcwd(),
// 128 => sys_getdirentry(),
// 128 => sys_dup(),
// 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);
::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 {
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());
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
}
fn sys_open(path: *const u8, flags: usize) -> i32 {
let path = unsafe { util::from_cstr(path) };
let flags = VfsFlags::from_ucore_flags(flags);
info!("open: path: {:?}, flags: {:?}", path, flags);
match path {
"stdin:" => 0,
"stdout:" => 1,
_ => -1,
"stdin:" => return 0,
"stdout:" => return 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 {
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.
@ -151,29 +216,25 @@ fn sys_putc(c: char) -> i32 {
0
}
const SYS_EXIT: usize = 1;
const SYS_FORK: usize = 2;
const SYS_WAIT: usize = 3;
const SYS_EXEC: usize = 4;
const SYS_CLONE: usize = 5;
const SYS_YIELD: usize = 10;
const SYS_SLEEP: usize = 11;
const SYS_KILL: usize = 12;
const SYS_GETTIME: usize = 17;
const SYS_GETPID: usize = 18;
const SYS_MMAP: usize = 20;
const SYS_MUNMAP: usize = 21;
const SYS_SHMEM: usize = 22;
const SYS_PUTC: usize = 30;
const SYS_PGDIR: usize = 31;
const SYS_OPEN: usize = 100;
const SYS_CLOSE: usize = 101;
const SYS_READ: usize = 102;
const SYS_WRITE: usize = 103;
const SYS_SEEK: usize = 104;
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;
bitflags! {
struct VfsFlags: usize {
// WARNING: different from origin uCore
const READABLE = 1 << 0;
const WRITABLE = 1 << 1;
/// create file if it does not exist
const CREATE = 1 << 2;
/// error if O_CREAT and the file exists
const EXCLUSIVE = 1 << 3;
/// truncate file upon open
const TRUNCATE = 1 << 4;
/// append on each write
const APPEND = 1 << 5;
}
}
impl VfsFlags {
fn from_ucore_flags(f: usize) -> Self {
assert_ne!(f & 0b11, 0b11);
Self::from_bits_truncate(f + 1)
}
}

Loading…
Cancel
Save