diff --git a/.travis.yml b/.travis.yml index 0f33674..3b2fc9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: rust rust: - - nightly \ No newline at end of file + - nightly-2018-04-01 \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 43be0a7..f98dd4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,7 @@ authors = ["WangRunji "] [dependencies] spin = "0.4" -bit-set = "0.5" \ No newline at end of file +bit-set = "0.5" + +[features] +ucore = [] \ No newline at end of file diff --git a/src/c_interface.rs b/src/c_interface.rs index 0b235fe..f9f01a9 100644 --- a/src/c_interface.rs +++ b/src/c_interface.rs @@ -1,5 +1,10 @@ //! C Interfaces for ucore +pub use self::allocator::UcoreAllocator; + +#[no_mangle] +pub static SFS_INODE_OPS: INodeOps = INodeOps::from_rust_inode::(); + /// Abstract low-level file. /// /// Match struct `inode` in ucore `kern/fs/vfs/inode.h` @@ -38,33 +43,127 @@ struct Stat { size: u32, } -const S_IFMT : u32 = 070000; // mask for type of file -const S_IFREG: u32 = 010000; // ordinary regular file -const S_IFDIR: u32 = 020000; // directory -const S_IFLNK: u32 = 030000; // symbolic link -const S_IFCHR: u32 = 040000; // character device -const S_IFBLK: u32 = 050000; // block device +/// mask for type of file +const S_IFMT: u32 = 070000; +/// ordinary regular file +const S_IFREG: u32 = 010000; +/// directory +const S_IFDIR: u32 = 020000; +/// symbolic link +const S_IFLNK: u32 = 030000; +/// character device +const S_IFCHR: u32 = 040000; +/// block device +const S_IFBLK: u32 = 050000; /// Abstract operations on a inode. /// /// Match struct `inode_ops` in ucore `kern/fs/vfs/inode.h` // TODO: Append docs from ucore #[repr(C)] -struct INodeOps { +pub struct INodeOps { magic: u64, - open: extern fn(*mut INode, flags: u32) -> i32, - close: extern fn(*mut INode) -> i32, - read: extern fn(*mut INode, *mut IoBuf) -> i32, - write: extern fn(*mut INode, *mut IoBuf) -> i32, - fstat: extern fn(*mut INode, *mut Stat) -> i32, - fsync: extern fn(*mut INode) -> i32, - namefile: extern fn(*mut INode, *mut IoBuf) -> i32, - getdirentry: extern fn(*mut INode, *mut IoBuf) -> i32, - reclaim: extern fn(*mut INode) -> i32, - gettype: extern fn(*mut INode, type_store: *mut u32) -> i32, - tryseek: extern fn(*mut INode, pos: i32) -> i32, - truncate: extern fn(*mut INode, len: i32) -> i32, - create: extern fn(*mut INode, name: *const u8, excl: bool, inode_store: *mut *mut INode) -> i32, - lookup: extern fn(*mut INode, path: *mut u8, inode_store: *mut *mut INode) -> i32, - ioctl: extern fn(*mut INode, op: i32, data: *mut u8) -> i32, + open: extern fn(*mut INode, flags: u32) -> ErrorCode, + close: extern fn(*mut INode) -> ErrorCode, + read: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, + write: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, + fstat: extern fn(*mut INode, *mut Stat) -> ErrorCode, + fsync: extern fn(*mut INode) -> ErrorCode, + namefile: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, + getdirentry: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, + reclaim: extern fn(*mut INode) -> ErrorCode, + gettype: extern fn(*mut INode, type_store: *mut u32) -> ErrorCode, + tryseek: extern fn(*mut INode, pos: i32) -> ErrorCode, + truncate: extern fn(*mut INode, len: i32) -> ErrorCode, + create: extern fn(*mut INode, name: *const u8, excl: bool, inode_store: *mut *mut INode) -> ErrorCode, + lookup: extern fn(*mut INode, path: *mut u8, inode_store: *mut *mut INode) -> ErrorCode, + ioctl: extern fn(*mut INode, op: i32, data: *mut u8) -> ErrorCode, +} + +#[repr(i32)] +#[derive(Debug)] +pub enum ErrorCode { + Ok = 0, + Unimplemented = -1, +} + +use vfs; +use sfs; + +impl INodeOps { + const fn from_rust_inode() -> Self { + extern fn open(inode: *mut INode, flags: u32) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn close(inode: *mut INode) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn read(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn write(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn fstat(inode: *mut INode, stat: *mut Stat) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn fsync(inode: *mut INode) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn namefile(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn getdirentry(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn reclaim(inode: *mut INode) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn gettype(inode: *mut INode, type_store: *mut u32) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn tryseek(inode: *mut INode, pos: i32) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn truncate(inode: *mut INode, len: i32) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn create(inode: *mut INode, name: *const u8, excl: bool, inode_store: *mut *mut INode) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn lookup(inode: *mut INode, path: *mut u8, inode_store: *mut *mut INode) -> ErrorCode { + ErrorCode::Unimplemented + } + extern fn ioctl(inode: *mut INode, op: i32, data: *mut u8) -> ErrorCode { + ErrorCode::Unimplemented + } + INodeOps { + magic: 0x8c4ba476, + open, close, read, write, fstat, fsync, namefile, getdirentry, + reclaim, gettype, tryseek, truncate, create, lookup, ioctl, + } + } +} + +mod allocator { + use alloc::heap::{Alloc, AllocErr, Layout}; + use core::ptr::NonNull; + + pub struct UcoreAllocator { + pub malloc: unsafe extern fn(size: usize) -> *mut u8, + pub free: unsafe extern fn(*mut u8), + } + + unsafe impl<'a> Alloc for &'a UcoreAllocator { + unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + const NULL: *mut u8 = 0 as *mut u8; + match (self.malloc)(layout.size()) { + NULL => Err(AllocErr::Exhausted { request: layout }), + ptr => Ok(ptr), + } + } + unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + (self.free)(ptr); + } + } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index d76f4dd..4e737d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,37 @@ #![feature(alloc)] #![feature(const_fn)] +#![cfg_attr(feature = "ucore", feature(allocator_api, global_allocator))] #![no_std] #[cfg(test)] #[macro_use] extern crate std; - extern crate spin; extern crate alloc; extern crate bit_set; +#[cfg(not(test))] +macro_rules! eprintln { + () => (); + ($fmt:expr) => (); + ($fmt:expr, $($arg:tt)*) => (); +} + mod dirty; mod vfs; mod sfs; mod structs; -mod c_interface; +#[cfg(feature = "ucore")] +pub mod c_interface; #[cfg(test)] -mod tests; \ No newline at end of file +mod tests; + +#[cfg(feature = "ucore")] +#[global_allocator] +pub static UCORE_ALLOCATOR: c_interface::UcoreAllocator = { + extern { + fn kmalloc(size: usize) -> *mut u8; + fn kfree(ptr: *mut u8); + } + c_interface::UcoreAllocator{malloc: kmalloc, free: kfree} +}; \ No newline at end of file