diff --git a/docs/2_OSLab/g5/exp3_1.md b/docs/2_OSLab/g5/exp3_1.md new file mode 100644 index 00000000..96e5e7cc --- /dev/null +++ b/docs/2_OSLab/g5/exp3_1.md @@ -0,0 +1,70 @@ +# 2018操作系统专题训练 + +# 实验3:实现和测试报告(续) + +计53 王润基 2015011279 + +2018.11.16 + +## 实验目标 + +**基于RustOS,参考sv6完成多核实现和优化。** + +分为以下三个子任务: + +1. 实现x86_64和RISCV下的多核启动和通信 +2. 拓展线程管理模块,使之支持多核调度 +3. 学习sv6进行多核优化 + +前两个目标在三周前上一次报告时已经完成。 + +后来经过考虑,发现补全RustOS的文件系统功能,是一件比多核优化更紧迫的任务,而且后者会依赖于前者。 + +因此,这三周的任务调整为:补全缺失的系统调用,目标能运行用户态shell。 + +## 实现过程 + +### 修复RV原子操作 + +* `__atomic_compare_exchange_4`之前的实现有Bug +* 直接给标准库打补丁,修复了`AtomicBool`的实现,不用再进行上层workaround + +### 修复RV32多核 + +* 原来context switch时忘了关中断 +* RV32下忘了开启其它核,包括:初始化页表,正确设置新用户进程的sstatus + +### 小的修改 + +* 开启了RV下串口中断。getchar改为阻塞式。 + + 当从串口输入字符时,由中断处理程序将其放入全局缓冲区中。 + + getchar从缓冲区中获取字符,如果为空则挂起等待。 + + 空闲时QEMU的CPU占用率保持在10%左右。 + +* 精简了x86 IDE驱动代码 + +### 修改SFS支持多线程 + +* 基于朱书聪这段时间来对SFS的改进。 +* 将全部Rc/RefCell替换为Arc/Mutex。 +* 反转INode和Fs的所有权关系。 +* 为INode实现Sync/Send,使得它可以定义在全局。 + +### 补全文件相关系统调用 + +* 实现了File对象(对应文件描述符层),简单包装INode对象,并加入权限检查。 +* 实现了系统调用read,write,open,close,fstat,dup,getdirentry。可以运行ls程序。 +* 实现了用户程序argc/argv。可以向ls传入参数。 +* 定义SysError错误类型,并在syscall中使用,简化错误处理代码。 +* 在INode接口下实现了Stdin/Stdout,可以作为文件使用了。 +* 实现系统调用sys_exec。用户程序sh可以正常运行! + +## 具体分析 + +* 文件系统部分,Rust总代码量近约1000行,而原版C的代码量有3000行! + + + diff --git a/docs/2_OSLab/g5/final.md b/docs/2_OSLab/g5/final.md new file mode 100644 index 00000000..fee12bdb --- /dev/null +++ b/docs/2_OSLab/g5/final.md @@ -0,0 +1,113 @@ +# 2018操作系统专题训练 + +# 最终报告 + +计53 王润基 2015011279 + +2018.12.27 + +## 本学期工作总结 + +* 实现各平台多核启动和调度 +* 完善文件系统相关功能 +* 实现NoMMU,RISCV M-Mode,RV64,K210支持 + +## 后半学期任务报告 + +### NoMMU + +#### 原理 + +* 去掉内存分页映射机制,将用户程序加载到任意地址运行 +* 内核为剩余物理内存空间建立另一个堆分配器(原来是用作物理帧) +* 当加载用户程序时,分配一段连续内存空间,并计算新的入口地址 + +#### 位置无关代码 + +- 用户程序需使用**相对寻址**: + - 代码段使用相对跳转 + - 数据段使用相对寻址,或去GOT(全局偏移表)查询地址 +- 为此需添加编译选项: + - 编译时`-fPIC`(位置无关代码) + - 链接时`-pie`(位置无关可执行程序) +- 原来ucore编译出的用户程序:x86绝对寻址,RISCV相对寻址 + +有待完善的地方: + +* 实现GOT表的填写,即可支持代码段和数据段分别分配地址 + +### RISCV M-Mode + +将现有的运行于S态的kernel移植到M态。 + +BBL为kernel提供了很多底层功能,因此需要保留。 + +#### 具体任务 + +* 去掉分页机制(NoMMU) +* 让BBL保持M态进入kernel +* 将kernel中操作的S-CSR改为M-CSR +* 融合kernel和BBL的运行环境 + +#### BBL提供的功能 + +* SBI:getchar,putchar,IPI +* 时间与时钟中断:模拟rdtime,提供set_timer() +* CPU不支持的指令模拟:乘除、浮点等 + +#### 融合kernel和BBL + +* 中断:原来kernel和BBL各有一套中断处理流程,融合后以kernel的为主体 +* SBI:BBL将相关函数符号传给kernel(BBL的角色变为静态库) +* 委托中断处理:当发生`IllegalInst`和`MachineEcall`异常时,调用BBL的函数处理 + +#### 问题 + +* QEMU中`mie.MEIE`(M态外设中断)不可开启,可能是个Bug。导致串口中断不工作,只能使用轮询方式getchar。 +* M态BBL是否还有存在的意义? + * RV下boot十分简单 + * BBL依赖FDT(设备树)初始化外设,但一般只有M态的开发版都不提供FDT。 + +### RV64 & K210 + +* 基于dzy同学的两阶段编译流程:Rust=>LLVM-IR=>Machine + +* 12月17日LLVM master已经完善地支持rv64,RustOS完整编译通过 +* 此后配合dzy完成rv64移植 + +#### 地址空间处理 + +* llc不支持code-model=medium,即位于任意地址4G范围内 +* 对此张蔚同学做了一个patch,但编译RustOS仍有问题,因此没用上 +* 于是目前只能将代码和数据放在+-2G区域,即[0,0x7fffffff], [0xffffffff_80000000, 0xffffffff_ffffffff] +* 在QEMU/HiFiveU上,支持S态、有页机制。因此将地址放在0xffffffff_80000000。需在BBL中设置初始页表并建立好映射,然后再进入S态Kernel +* K210上RAM位于0x80000000,但也可以通过0x40000000访问(无cache)。因此将地址放在0x40000000。 + +#### K210适配 + +* 主要参考官方SDK +* 串口: + * 使用UARTHS,和普通UART规范不一致 + * 在boot阶段就初始化好,方便调试 + * TODO:串口事件中断 +* 原子操作: + - 原子指令对0x40000000地址区无效(???) + - 解决方法:在自己实现的`__atomic_*`函数中将地址移到0x80000000处。 +* 多核: + * reset后同时开始运行,不需额外boot + * 目前只用了单核,因为还有Bug…… +* 时钟中断: + * SDK中的处理较为复杂,懒得重新造轮子 + * 将SDK编译为静态库,链接到kernel,kernel导入符号使用 +* 修复前期M-Mode的Bug + +#### 搞K210的困难 + +* 没有完整的模拟器(其实部分也够了) +* 烧程序慢,导致实验验证周期长(提高波特率:2min->0.5min) + +### 其它 + +* 适配 Rust 2018 edition +* 实现文件内存映射,用户程序内存均延迟分配,以后可实现mmap +