mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
impl file syscalls, without test
This commit is contained in:
parent
200a574a1f
commit
e27aea47e1
2
kernel/Cargo.lock
generated
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…
Reference in New Issue
Block a user