内核接入easy-fs
/// OS里操作的索引节点类型,封装了easy-fs中的Inode
pub struct OSInode {
/// 是否可读
readable: bool,
/// 是否可写
writable: bool,
/// 偏移
offset: Cell<usize>,
/// 封装easy-fs中的Inode
inode: Cell<Arc<Inode>>,
}
内核中封装了easy-fs中的Inode,使用OSInode结构来对单个文件进行操作。
/// 全局变量:根节点的索引节点
pub static ROOT_INODE: Cell<Arc<Inode>> = unsafe { transmute([1u8; size_of::<Arc<Inode>>()]) };
/// 文件系统初始化,创建root inode
pub fn init() {
let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
unsafe {
(ROOT_INODE.get() as *mut Arc<Inode>).write(Arc::new(EasyFileSystem::root_inode(&efs)));
}
println!("/****APPS****/");
for app in ROOT_INODE.ls() {
println!("{}", app);
}
println!("**************/");
}
为根节点创建Inode后,我们使用全局变量ROOT_INODE来创建或打开文件
/// 根据OpenFlags打开根节点下的文件
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Rc<OSInode>> {
let (readable, writable) = flags.read_write();
if flags.contains(OpenFlags::CREATE) {
if let Some(inode) = ROOT_INODE.find(name) {
inode.clear();
Some(Rc::new(OSInode::new(readable, writable, inode)))
} else {
// create file
ROOT_INODE
.create(name)
.map(|inode| Rc::new(OSInode::new(readable, writable, inode)))
}
} else {
ROOT_INODE.find(name).map(|inode| {
if flags.contains(OpenFlags::TRUNC) {
inode.clear();
}
Rc::new(OSInode::new(readable, writable, inode))
})
}
}
由于easy-fs为扁平化结构,所有文件都在根目录下,所以现在我们可以在文件系统中打开所有用户程序了。如在内核中创建root进程:
// 创建根进程
fn main() {
...
info!("[Kernel] Load root");
let root_file = open_file("root", OpenFlags::RDONLY).unwrap();
let elf_data = root_file.read_all();
let root_process = Process::new(String::from("root"), &elf_data, None);
}