第一阶段
我其实在去年的时候就对训练营略有耳闻,但是由于在准备算法竞赛,并且对未来研究生的方向还没有一个明确的规划,所以没有参加。而现在,我基本上已经确定了未来要往体系结构和操作系统方向发展,所以第一时间便报名参加了训练营。
第一阶段学的内容是 Rust。Rust 也是我很喜欢的一门语言,因为他性能高、内存安全、又有良好的包管理器支持,相比于 C、C++,它的语言表达能力更加强大,也有很多好用的语法糖;而相比于 Java、Python 等,它又更为严谨、更贴近硬件。
经过这一段时间的学习,我越学越觉得 Rust 的很多特性其实是为了给他严格的所有权机制打补丁。最明显的就是生命周期了,还有诸如 unsafe
等。刚好最近同时也在一家公司实习做操作系统内核开发,正在使用 C 语言,因此对这两门语言的风格深有所感:
- C 的原则就是「完全相信使用者」,因此你可以用 C 实现几乎所有操作,非常自由。但是为了安全,必须人为设计一些规范来进行约束。
- Rust 的原则则是「完全不相信使用者」,所以你会发现 Rust 的很多语法都是为了约束程序员,强迫程序员写出安全的代码。但是,有些时候编译器还是不够聪明,或者说是无法进行判断,因此必须开点绿灯——
unsafe
。
在 Rust 身上可以找到很多为了弥补所有权机制而设计的语法,因此在学习的时候才会觉得 Rust 的语法很复杂。不过这种「语言规定好的规范」对于多人之间的项目合作,特别是开源来说,就是一种优势了。相比于 C 语言项目之间可能存在代码风格相差巨大的情况,Rust 写出来的代码基本上不会有太大的风格差异,这样在参考别人的代码,以及贡献代码的时候就会更为轻松。
第二阶段
第二阶段开始进入操作系统领域的学习了。训练营采用的是清华大学的 rcore 教程,不过相比原版的 rCore-Tutorial-v3 有了很大的变化,删去了很多不必要的任务,任务的指引也更加清晰,教材方面也根据代码做了很多简化。整体上是更容易上手了。
在这几章的学习内容中,我认为最难理解的是虚拟地址页表那一章。一开始我一直困惑于“操作系统到底如何分配内存,如何知道地址是否合法的”,后来经过了解才知道,虚拟地址其实是软件和硬件共同实现的,操作系统需要做的是维护页表,而 cpu 会利用操作系统维护的页表,通过硬件来判断地址是否合法,以及将虚拟地址转换为真实的物理地址。所以整个计算机的发展软硬件是不可分开的。
在完成了第二阶段的学习后,我和队友便着手开始了计算机系统能力大赛的开发。一开始我们是打算基于 arceos 进行开发的,但是了解后才发现 arceos 似乎没有提供一个基础的内核框架,而只是提供了很多的“组件”,而我们此时仅剩下不到两周的时候,根本无法在这么短的时间从头自己写一个内核出来,因此最后还是选择基于训练营第二阶段结束后的 rcore 版本进行开发。
也是得益于训练营阶段对 rcore 代码深入学习的经历,让我们在两周不到的时间里,完全原创地完成了操作系统比赛初赛的赛题。接下来是复赛,我们打算继续基于初赛的代码,加入虚拟文件系统、无栈协程等特性,为复赛做好准备!
第三阶段
第三阶段我选择了项目二《ArceOS 宏内核》,原因是我正在参加今年的计算机系统能力大赛(操作系统内核实现赛道),正好项目二和我们的比赛内容较为贴近,可以相互之间参考与借鉴一下。
ArceOS 是 unikernel。其特点是模块组件化,这样在构建操作系统镜像的时候,就可以选择性地编译模块,从而达到尽可能减少系统镜像体积的目的,对嵌入式等低性能的场景有很大的帮助。
但是 unikernal 的缺点是没有用户态和内核态的区分,也就意味着应用程序的权限管理会对内核的稳定性有很大的隐患。其次,ArceOS 目前只支持一个应用程序,不能作为一个通用的内核来使用。
因此,项目二的目的就是为了让 ArceOS 支持用户态和内核态、支持多应用的并发执行,向宏内核靠拢。