rustling
大部分练习没什么印象,都是很基础的练习。
唯一印象深刻的是对#[cfg(feature)]
的考察,cargo在编译时会根据feature来选择编译字段、函数、源代码,私认为这是个很有用的特性。在编译大型项目时,就可以塞入很多功能,让用户能够选择feature来控制项目的编译。
rcore
之前做过mit 6.1810
操作系统实验课,是基于riscv
的用c
编写的操作系统。这次写rcore
主要是体验两者在实验流程的设计差异,以及c
和rust
在编写内核上的特性与差异。
我个人觉得rcore
内容上更丰厚更复杂,但是实验设计上有点太简单了,或者说为学生实现了太多。我觉得可以丰富实验内容,让学生体会到内核的调用流程,以及rust
语言实现内核的优点。
在
syscall
实验中,可以增加几个系统调用函数,并让学生完成从用户态增加函数,到内核态具体实现在
syscall
实验中,内核接收syscall_id
,通过match分发到对应的函数。我个人觉得这里应该提供两个数组引导学生去填写新增的系统调用函数:index -> syscall_id
:SYSCALL_MAP = [SYS_GETTIME, SYS_READ, SYS_WRITE, .. ]
index -> syscall_func
:SYSCALL_FUNC = [sys_gettime, sys_read, sys_write, ..]
这样,很自然的就能想到
trace
系统调用应该怎么实现。我觉得syscall_id
设置成64,93,124,...
应该有rcore
设计上的考量,教学项目是不是可以设置从0开始的连续自然数呢?在
virtual memory
中,实验设计书上没有仔细讲从虚拟地址的39位怎么映射到物理地址的,而代码更是直接帮学生实现好了地址转换、地址映射、地址查找。我个人觉得这里可以划分几个实验让学生实现在
virtual memory
中,增加一个中断实验,内核处理page_fault
,进而进一步考察copy on write
页表缺页的实验接上一条,增加
trap
的处理实验增加考察汇编代码的简单编写,比如在代码中插入汇编代码、在
.S
中编写汇编代码。并让学生体会为什么这么做:手动控制寄存器。在这个过程中,自然的就了解了编写的函数本质就是汇编代码中的符号,再通过汇编链接到一起测试可以更丰富,有些测试过于简单了
用户端的
shell
代码应该捕获ctrl z, ctrl d, ctrl c
之类的字符或者添加exit, quit
来让用户退出
在这次实验中,我深刻体会到了rust
在trait
抽象的强大之处,在virtual memory
实验中,VirtAddr
和PhyAddr
的struct
对相关trait
的实现可以很方便让用户操作地址还不会混淆。
arceos
非常的复杂,内容也非常的多。我一直认为大型项目的价值在于项目的架构以及各个api的语义设计。
通过查看调用链了解到了是user -> axstd -> api -> modules/xxx
。我觉得这个项目最有意思的地方在于组件化操作系统,通过feature
来选择编译Unikernel
、宏内核、虚拟机。如果组件化内核编译出的各种类型内核性能与原生内核差距不大的话,感觉会是很方便的内核开发方式。
郑友捷老师讲的组件化内核让我收益很多,我准备后续学习一下cargo的功能来了解这个项目是怎么组织不同功能的组件的。
我自己一直有个疑惑,编写内核的时候要不要用alloc::collections中的数据结构,以及为了内核稳定性是不是应该只用官方库和自己编写的库而少用第三方库。
这个项目也让我逐渐意识到一个事实:编译器提供c语言库,其他高级语言通过调用c语言库(汇编)来与硬件/操作系统交互。