From ae77625e231158f73ac06d232319d433eb3606f9 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 27 Mar 2019 18:04:22 +0800 Subject: [PATCH] remove legacy report --- README.md | 3 +- docs/rust_port_report.md | 243 --------------------------------------- 2 files changed, 1 insertion(+), 245 deletions(-) delete mode 100644 docs/rust_port_report.md diff --git a/README.md b/README.md index 1a92049..47cb9db 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,11 @@ Core: * `rcore-fs`: Interfaces and utilities that can be used in an OS. * Virtual File System: `FileSystem`, `INode` * Device and cache layer: `BlockDevice`, `CachedDevice`(TODO) - * Unit tests for VFS Specific file systems: * `rcore-fs-sfs`: Simple File System from [uCore OS](https://github.com/chyyuu/ucore_os_lab) -* `rcore-fs-sefs`: Simple Encrypt File System +* `rcore-fs-sefs`: Simple Encrypted File System * `rcore-fs-fat32`: (TODO) FAT32 * `rcore-fs-ramfs`: (TODO) RAM based FS. * `rcore-fs-devfs`: (TODO) Device driver as files diff --git a/docs/rust_port_report.md b/docs/rust_port_report.md deleted file mode 100644 index 6dce5fa..0000000 --- a/docs/rust_port_report.md +++ /dev/null @@ -1,243 +0,0 @@ -# SimpleFileSystem Rust移植报告 - -王润基 2018.05.05 - -## 任务目标 - -* 用Rust重新实现SFS模块,力求精简 -* 以crate库的形式发布,不依赖OS,支持单元测试 -* 导出兼容ucore的C接口,能链接到ucore lab8中替换原有实现 -* 在RustOS中使用 - -## 结构设计 - -自底向上: - -#### 硬盘数据结构层 - -和SFS在硬盘上具体的存储结构相关。位于`structs.rs`。 - -这部分定义了硬盘上的数据结构,完全照搬C中的定义,并实现了一些Rust辅助方法。 - -#### SFS层 - -和SFS在内存中的对象相关。位于`sfs.rs`。 - -这部分主要定义了两个对象:`SimpleFileSystem`和`INode`。 - -它们依赖下层的具体结构,实现上层VFS的接口,完成具体的文件操作。 - -由于利用了Rust的一些模块的特性,这两个结构体的定义和C中很不一样。 - -#### VFS层 - -文件系统通用接口。位于`vfs.rs`。 - -这部分主要定义了三个接口:`FileSystem`,`INode`,`Device`。 - -其中前两个是需要具体文件系统实现的。Device是依赖项,提供读写方法。 - -它们基本照搬C中的定义,但换成了Rust风格,更加本质。 - -由于C在语言层面缺乏对接口的支持,ucore中是用struct和函数指针实现接口功能。但在Rust中就是简单的Trait。 - -#### C兼容层 - -将Rust风格的VFS导出为ucore可用的C接口。位于`c_interface.rs`。 - -这部分导入了ucore中`stat` `iobuf` `device`等结构,将他们实现Rust的Trait。同时将VFS层中的Trait转化成C函数接口。 - -除此之外,还要导入ucore中的一些基础设施,例如`kmalloc` `kfree` `cprintf` `panic` - -## Rust带来的好处 - -* 利用RAII特性,使用一些小Wrapper结构,进行自动标记和断言,大大减轻开发者心智负担。例如:Mutex锁,RefCell访问检查,Dirty脏标记,Rc引用计数。 -* 从始至终严格的访问控制,只要不滥用unsafe,可快速并行化,并保证安全。 -* 语言描述能力强,代码量少。对比C的SFS模块1100+行,Rust只用了700+行(除去单元测试和C兼容层)。 - -## 接下来的目标 - -* 接入ucore中能够跑起来 -* 实现mksfs等周边工具 -* 多线程支持及并行优化 - - - -## 与ucore_os_lab8 对接报告 - -王润基 2018.05.07 - -搞定这事儿耗费了大约15小时的时间 - -### 实现的功能 - -通过C兼容层将Rust VFS接口和ucore VFS层对接起来。 - -经测试,在shell中能够正常执行各个程序,`ls`输出正确。 - -在实现上:清理掉ucore_os_lab8的sfs文件夹,只留下`sfs.h`(未修改)和`sfs.c`(添加少许辅助函数)。再将Rust SFS编译成静态库,链接到kernel中。 - -### 如何运行 - -整合之后的ucore可以从[这里](https://github.com/wangrunji0408/ucore_os_lab/tree/rust-fs/labcodes_answer/lab8_result)获得。 - -```bash -# 下载项目 -git clone https://github.com/wangrunji0408/ucore_os_lab.git -b rust-fs --recursive -# 切到lab8目录 -cd ucore_os_lab/labcodes_answer/lab8_result/ -# 如果没有安装Rust,用以下命令,但愿能work -make -f rust_sfs/Makefile install-rust -# 编译运行 -make qemu -``` - -### 如何调试 - -我使用CLion + Rust插件编写代码。 - -调试时,首先用`make dbg4ec`开启QEMU,再用CLion中自带的`GDB Remote Debug`连接上去,即可GUI调试。此外还需在ucore的makefile中添加编译参数`-g`,才能在CLion中定位C的源代码。 - -### 遇到的问题 - -- 链接丢失: - - ucore_os_lab的linker script少写了一些section,包括`*.data.*` `*.got.*` `*.bss.*`,导致Rust lib链接过去后丢失了一些段,比较坑的是这不会有任何提示。没有成功重定位的地址都是0,运行时直接Page fault。为了找出出错位置,各种gdb,objdump全上了,还得看汇编追踪寄存器,真是大坑。 - -- 引用LLVM内置函数: - - Rust lib会引用一些LLVM内置函数(如udivdi3,都是除法运算相关),链接时会报undefined symbol。但实际上并没有代码用到它们。《Writing an OS in Rust》中提到了这个问题,它的解决方案是链接时加`--gc-sections`选项,将未用到的段删掉,结果我对ucore如此操作之后所有段都没了,都boot不起来。。。最后是在C中强行定义这些符号解决的。 - -- 对ucore VFS接口理解的歧义: - - 例如:`getdirentry`,`gettype` - - 经常需要查看ucore SFS的原始实现,以及输出它传给我的结构内容,才能理解它到底是如何工作的。 - -### C兼容层的设计 - -#### ucore VFS分析 - -```c -// [1] SFS模块的入口点。从这里获得fs。 -int sfs_do_mount(struct device *dev, struct fs **fs_store); - -struct fs { - // 头部是具体文件系统的内容 - union { - struct sfs_fs __sfs_info; - } fs_info; - - // 元信息 - enum { - fs_type_sfs_info, - } fs_type; - - // 虚函数表 - int (*fs_sync)(struct fs *fs); - // [2] 从这里获得inode - struct inode *(*fs_get_root)(struct fs *fs); - int (*fs_unmount)(struct fs *fs); - void (*fs_cleanup)(struct fs *fs); -}; - -struct inode { - // 头部是具体文件系统的内容 - union { - struct device __device_info; - struct sfs_inode __sfs_inode_info; - } in_info; - - // 元信息,引用计数 - enum { - inode_type_device_info = 0x1234, - inode_type_sfs_inode_info, - } in_type; - int ref_count; - int open_count; - - // 引用fs - struct fs *in_fs; - - // 虚函数表 - // [3] 通过其中的lookup()/create()获得其他inode - const struct inode_ops *in_ops; -}; -``` - -#### Rust VFS分析 - -```rust -type INodePtr = Rc>; - -pub trait FileSystem { - // [1] 从这里获得FS - fn new(device: Box) -> Result; - // [2] 从这里获得INode - fn root_inode(&self) -> INodePtr; - // 其他函数... -} - -pub trait INode { - // 引用fs - fn fs(&self) -> Weak; - // [3] 获得其他INode - fn lookup(&self, path: &'static str) -> Result; - // 其他函数... -} -``` - -#### 如何合并 - -ucore VFS中fs和inode头部是具体FS的struct。Rust VFS使用Rc指针相互引用。为了将它们合并起来,考虑过两种方案: - -* **在头部放Rc指针** - * Rust VFS = ucore SFS - * 还需建立Rust INode => ucore INode的反向引用 - * 要么侵入式地增加Rust INode的字段 - * 要么**在兼容层搞一个全局Map** - * 这种方式耦合较低,但多一层指针跳转,性能可能略差。 -* 在头部放Rust SFS的结构本体 - * Rust VFS = ucore VFS - * 需要在Rust new出SFS结构时做文章, 委托ucore分配多一点空间并做VFS的初始化,得魔改Rust的全局内存分配器。 - * 这种方式耦合较高,需对Rust结构的实际内存布局有深入理解。 - -最终采取的方案加粗表示。 - -在这个框架下,将ucore虚函数表中的每一个都用RustVFS提供的接口去实现,并处理参数格式转化。以比较复杂的`lookup`为例: - -```rust -// 这个函数的地址保存在虚表中,传给ucore -extern fn lookup(inode: &mut INode, path: *mut u8, inode_store: &mut *mut INode) -> ErrorCode { - // 【参数处理】将C字符串转为Rust字符串 - let path = unsafe{ libc::from_cstr(path) }; - // 【完成功能】调用 Rust VFS 的函数 - let target = inode.borrow().lookup(path); - // 【结果处理】 - match target { - Ok(target) => { - // 从ucore inode中获取ucore fs - let fs = unsafe{ ucore::inode_get_fs(inode) }; - // 使用全局Map,将Rust INode映射为ucore inode,如果不存在则新建一个(要用到ucore fs) - let inode = INode::get_or_create(target, fs); - // 按ucore接口要求,增加引用计数 - unsafe { ucore::inode_ref_inc(inode) }; - // 给出ucore inode - *inode_store = inode; - ErrorCode::Ok - }, - // 设置正确的错误码 - Err(_) => ErrorCode::NoEntry, - } -} -``` - -经过统计,`C兼容层`的有效代码量约500行,和实现核心功能的`Rust SFS层`相当。说明这种胶水代码真是又臭又长,搞兼容性都是脏活累活。 - -### 那么……意义何在? - -* 将FS模块接入实际OS,验证其可行性和可靠性(尤其是在RustOS还遥遥无期的背景下……) -* 检验了Rust和C的互操作性,证明Rust编写系统模块是可行的。 -* (试图)为ucore提供一套更好更实用的文件系统接口(个人认为Rust接口更容易去实现),方便日后将其他FS接入(如CS140e.FAT32) -* (也许)能为OS教学提供另一种可能性 -* 锻炼了我的跨语言+汇编级别debug能力,让我对ucore FS有更深入的了解 \ No newline at end of file