Try to link with ucore

master
WangRunji 7 years ago
parent d04829959c
commit dd62ea7335

@ -3,9 +3,15 @@ name = "simple-filesystem"
version = "0.0.1" version = "0.0.1"
authors = ["WangRunji <wangrunji0408@163.com>"] authors = ["WangRunji <wangrunji0408@163.com>"]
[lib]
crate-type = ["staticlib"]
[profile.dev]
panic = 'abort' # prevent `_Unwind_Resume` link error
[dependencies] [dependencies]
spin = "0.4" spin = "0.4"
bit-set = "0.5" bit-set = { default-features = false, version = "0.5" } # default-features contains 'std'
[features] [features]
ucore = [] ucore = []

@ -0,0 +1,2 @@
ucore:
@RUST_TARGET_PATH=$(shell pwd) xargo build --target ucore --features ucore

@ -0,0 +1,2 @@
[target.ucore.dependencies]
alloc = {}

@ -1,16 +1,92 @@
//! C Interfaces for ucore //! C Interfaces for ucore
use alloc::{rc::Rc, boxed::Box};
use core::cell::RefCell;
use core::slice;
/// Global allocator defined in root
pub use self::allocator::UcoreAllocator; pub use self::allocator::UcoreAllocator;
/// Lang items for bare lib
mod lang {
use core;
#[lang = "eh_personality"]
#[no_mangle]
extern fn eh_personality() {
}
#[lang = "panic_fmt"]
#[no_mangle]
extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! {
eprintln!("\n\nPANIC in {} at line {}:", file, line);
eprintln!(" {}", fmt);
use super::ucore::__panic;
unsafe{ __panic() };
unreachable!()
}
}
/// Depends on ucore
mod ucore {
use super::*;
extern {
pub fn __alloc_inode(type_: i32) -> *mut INode;
pub fn inode_init(inode: &mut INode, ops: &INodeOps, fs: &mut Fs);
pub fn inode_kill(inode: &mut INode);
pub fn __alloc_fs(type_: i32) -> *mut Fs;
pub fn __panic();
}
pub const SFS_TYPE: i32 = 0; // TODO
}
// Exports for ucore
static SFS_INODE_OPS: INodeOps = INodeOps::from_rust_inode::<sfs::INode>();
//static SFS_FS: *mut Fs = 0 as *mut _;
#[no_mangle] #[no_mangle]
pub static SFS_INODE_OPS: INodeOps = INodeOps::from_rust_inode::<sfs::INode>(); pub extern fn sfs_do_mount(dev: *mut Device, fs_store: &mut *mut Fs) -> ErrorCode {
use self::ucore::*;
let fs = unsafe{__alloc_fs(SFS_TYPE)};
let device = unsafe{ Box::from_raw(dev) }; // TODO: fix unsafe
unsafe{&mut (*fs)}.fs = sfs::SimpleFileSystem::open(device).unwrap();
*fs_store = fs;
ErrorCode::Ok
}
// Structs defined in ucore
/// Abstract low-level file. /// Abstract low-level file.
/// ///
/// Match struct `inode` in ucore `kern/fs/vfs/inode.h` /// Match struct `inode` in ucore `kern/fs/vfs/inode.h`
#[repr(C)] #[repr(C)]
struct INode { struct INode {
// TODO: full the struct inode: Rc<RefCell<vfs::INode>>,
// ... fields handled extern
}
/// Abstract filesystem. (Or device accessible as a file.)
///
/// Match struct `fs` in ucore `kern/fs/vfs/vfs.h`
#[repr(C)]
pub struct Fs {
fs: Rc<vfs::FileSystem>,
// ... fields handled extern
}
/// Filesystem-namespace-accessible device.
/// d_io is for both reads and writes; the iobuf will indicates the direction.
///
/// Match struct `device` in ucore `kern/fs/devs/dev.h`
#[repr(C)]
pub struct Device {
blocks: usize,
blocksize: usize,
open: extern fn(&mut Device, flags: u32) -> ErrorCode,
close: extern fn(&mut Device) -> ErrorCode,
io: extern fn(&mut Device, buf: &mut IoBuf, is_write: bool) -> ErrorCode,
ioctl: extern fn(&mut Device, op: i32, data: *mut u8) -> ErrorCode,
} }
/// A buffer Rd/Wr status record /// A buffer Rd/Wr status record
@ -63,78 +139,164 @@ const S_IFBLK: u32 = 050000;
#[repr(C)] #[repr(C)]
pub struct INodeOps { pub struct INodeOps {
magic: u64, magic: u64,
open: extern fn(*mut INode, flags: u32) -> ErrorCode, open: extern fn(&mut INode, flags: u32) -> ErrorCode,
close: extern fn(*mut INode) -> ErrorCode, close: extern fn(&mut INode) -> ErrorCode,
read: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, read: extern fn(&mut INode, &mut IoBuf) -> ErrorCode,
write: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, write: extern fn(&mut INode, &mut IoBuf) -> ErrorCode,
fstat: extern fn(*mut INode, *mut Stat) -> ErrorCode, fstat: extern fn(&mut INode, &mut Stat) -> ErrorCode,
fsync: extern fn(*mut INode) -> ErrorCode, fsync: extern fn(&mut INode) -> ErrorCode,
namefile: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, namefile: extern fn(&mut INode, &mut IoBuf) -> ErrorCode,
getdirentry: extern fn(*mut INode, *mut IoBuf) -> ErrorCode, getdirentry: extern fn(&mut INode, &mut IoBuf) -> ErrorCode,
reclaim: extern fn(*mut INode) -> ErrorCode, reclaim: extern fn(&mut INode) -> ErrorCode,
gettype: extern fn(*mut INode, type_store: *mut u32) -> ErrorCode, gettype: extern fn(&mut INode, type_store: &mut u32) -> ErrorCode,
tryseek: extern fn(*mut INode, pos: i32) -> ErrorCode, tryseek: extern fn(&mut INode, pos: i32) -> ErrorCode,
truncate: extern fn(*mut INode, len: 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, 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, 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, ioctl: extern fn(&mut INode, op: i32, data: &mut u8) -> ErrorCode,
} }
#[repr(i32)] #[repr(i32)]
#[derive(Debug)] #[derive(Debug, Eq, PartialEq)]
pub enum ErrorCode { pub enum ErrorCode {
Ok = 0, Ok = 0,
Unimplemented = -1, Unimplemented = -1,
} }
// Wrapper functions
use vfs; use vfs;
use sfs; use sfs;
impl AsRef<[u8]> for IoBuf {
fn as_ref(&self) -> &[u8] {
unsafe{ slice::from_raw_parts(self.base, self.resident as usize) }
}
}
impl AsMut<[u8]> for IoBuf {
fn as_mut(&mut self) -> &mut [u8] {
unsafe{ slice::from_raw_parts_mut(self.base, self.resident as usize) }
}
}
impl IoBuf {
fn skip(&mut self, len: usize) {
assert!(len as u32 <= self.resident);
self.base = unsafe{ self.base.offset(len as isize) };
self.offset += len as i32;
self.resident -= len as u32;
}
}
impl sfs::Device for Device {
fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option<usize> {
let mut io_buf = IoBuf {
base: buf.as_mut_ptr(),
offset: offset as i32,
len: buf.len() as u32,
resident: buf.len() as u32,
};
let ret = (self.io)(self, &mut io_buf, false);
assert_eq!(ret, ErrorCode::Ok);
Some(buf.len() - io_buf.resident as usize)
}
fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option<usize> {
let mut io_buf = IoBuf {
base: buf.as_ptr() as *mut u8,
offset: offset as i32,
len: buf.len() as u32,
resident: buf.len() as u32,
};
let ret = (self.io)(self, &mut io_buf, true);
assert_eq!(ret, ErrorCode::Ok);
Some(buf.len() - io_buf.resident as usize)
}
}
impl INode {
fn new() -> *mut Self {
use self::ucore::*;
let ptr = unsafe{ __alloc_inode(SFS_TYPE) };
assert!(!ptr.is_null());
// inode_init(ptr, &SFS_INODE_OPS as *const _, SFS_FS);
ptr
}
fn drop(&mut self) {
use self::ucore::*;
unsafe{ inode_kill(self) };
}
}
impl From<vfs::FileInfo> for Stat {
fn from(info: vfs::FileInfo) -> Self {
Stat {
mode: info.mode,
nlinks: 0,
blocks: info.blocks as u32,
size: info.size as u32,
}
}
}
impl INodeOps { impl INodeOps {
const fn from_rust_inode<T: vfs::INode>() -> Self { const fn from_rust_inode<T: vfs::INode>() -> Self {
extern fn open(inode: *mut INode, flags: u32) -> ErrorCode { extern fn open(inode: &mut INode, flags: u32) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn close(inode: *mut INode) -> ErrorCode { extern fn close(inode: &mut INode) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn read(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { extern fn read(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
ErrorCode::Unimplemented let inode = &inode.inode;
let len = inode.borrow().read_at(buf.offset as usize, buf.as_mut()).unwrap();
buf.skip(len);
ErrorCode::Ok
} }
extern fn write(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { extern fn write(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
ErrorCode::Unimplemented let inode = &inode.inode;
let len = inode.borrow().write_at(buf.offset as usize, buf.as_ref()).unwrap();
buf.skip(len);
ErrorCode::Ok
} }
extern fn fstat(inode: *mut INode, stat: *mut Stat) -> ErrorCode { extern fn fstat(inode: &mut INode, stat: &mut Stat) -> ErrorCode {
ErrorCode::Unimplemented let inode = &inode.inode;
let info = inode.borrow().info().unwrap();
*stat = Stat::from(info);
ErrorCode::Ok
} }
extern fn fsync(inode: *mut INode) -> ErrorCode { extern fn fsync(inode: &mut INode) -> ErrorCode {
ErrorCode::Unimplemented inode.inode.borrow_mut().sync().unwrap();
ErrorCode::Ok
} }
extern fn namefile(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { extern fn namefile(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn getdirentry(inode: *mut INode, buf: *mut IoBuf) -> ErrorCode { extern fn getdirentry(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn reclaim(inode: *mut INode) -> ErrorCode { extern fn reclaim(inode: &mut INode) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn gettype(inode: *mut INode, type_store: *mut u32) -> ErrorCode { extern fn gettype(inode: &mut INode, type_store: &mut u32) -> ErrorCode {
ErrorCode::Unimplemented let inode = &inode.inode;
let info = inode.borrow().info().unwrap();
*type_store = info.type_ as u32;
ErrorCode::Ok
} }
extern fn tryseek(inode: *mut INode, pos: i32) -> ErrorCode { extern fn tryseek(inode: &mut INode, pos: i32) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn truncate(inode: *mut INode, len: i32) -> ErrorCode { extern fn truncate(inode: &mut INode, len: i32) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn create(inode: *mut INode, name: *const u8, excl: bool, inode_store: *mut *mut INode) -> ErrorCode { extern fn create(inode: &mut INode, name: *const u8, excl: bool, inode_store: &mut &mut INode) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn lookup(inode: *mut INode, path: *mut u8, inode_store: *mut *mut INode) -> ErrorCode { extern fn lookup(inode: &mut INode, path: &mut u8, inode_store: &mut &mut INode) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
extern fn ioctl(inode: *mut INode, op: i32, data: *mut u8) -> ErrorCode { extern fn ioctl(inode: &mut INode, op: i32, data: &mut u8) -> ErrorCode {
ErrorCode::Unimplemented ErrorCode::Unimplemented
} }
INodeOps { INodeOps {

@ -1,6 +1,6 @@
#![feature(alloc)] #![feature(alloc)]
#![feature(const_fn)] #![feature(const_fn)]
#![cfg_attr(feature = "ucore", feature(allocator_api, global_allocator))] #![cfg_attr(feature = "ucore", feature(allocator_api, global_allocator, lang_items))]
#![no_std] #![no_std]
#[cfg(test)] #[cfg(test)]

@ -239,6 +239,7 @@ impl vfs::INode for INode {
size: self.disk_inode.size as usize, size: self.disk_inode.size as usize,
mode: 0, mode: 0,
type_: vfs::FileType::from(self.disk_inode.type_.clone()), type_: vfs::FileType::from(self.disk_inode.type_.clone()),
blocks: self.disk_inode.blocks as usize,
}) })
} }
fn sync(&mut self) -> vfs::Result<()> { fn sync(&mut self) -> vfs::Result<()> {

@ -70,6 +70,7 @@ fn create_file() {
size: 0, size: 0,
type_: FileType::File, type_: FileType::File,
mode: 0, mode: 0,
blocks: 0,
}); });
sfs.sync().unwrap(); sfs.sync().unwrap();

@ -27,6 +27,7 @@ pub struct FileInfo {
pub size: usize, pub size: usize,
pub mode: u32, pub mode: u32,
pub type_: FileType, pub type_: FileType,
pub blocks: usize,
} }
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]

@ -0,0 +1,16 @@
{
"cpu": "pentium4",
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
"llvm-target": "i686-unknown-none",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"features": "-mmx,-sse,+soft-float",
"os": "none",
"arch": "x86",
"linker-flavor": "ld",
"pre-link-args": ["-m32"],
"eliminate-frame-pointer": false,
"morestack": false,
"panic-strategy": "abort"
}
Loading…
Cancel
Save