0%

2023开源操作系统训练营第二阶段总结报告-郝淼

关于开源操作系统训练营

我是在一年前关注到“开源操作系统训练营”这个活动的,但是苦于那时在进行本科毕业设计工作,没有抽出时间来参加。在那时,我就已经对系统软件、 Rust很感兴趣了,因此本科毕业设计做的也是 OS 相关的工作。如今在研一,课业之外有了一部分时间,想用来提升自身对 OS 前沿的认识,同时积累一些工程经验,于是便参加了今年的开源 OS 训练营。

关于 Rust

Rust 是一门比较新的系统级编程语言,我最早听说 Rust 是在一次高中同学聚会上。那时候,我的一位高中同学所在的大学(不是清华)已经使用 Rust 来布置一些课程的大作业,而我所在的大学还没有涉及 Rust 的课程。

我对 Rust 最深刻的印象是“内存安全”和“系统级编程语言”,但之后的很长一段时间里,我都没有去更深入地了解 Rust 了,原因很简单:没有时间、对课程也没什么帮助。

后来,做毕业设计的时候,导师偶尔会提到一些清华大学陈渝老师组的一些 OS 方面的前沿研究工作,比如押宝 Rust、组件化 OS 之类的。因此,我对 Rust 的认识也在发生转变。实际上,OS 发展中一个重要的影响因素就是系统级编程语言,而 Rust 作为一门比较新的系统级编程语言,未来势必影响 OS 的发展。

经过了两个阶段的学习,我对 Rust 的特点有了更深入的认识:Rust 解决的内存安全问题的方法是将相当一部分内存安全检查放到了编译时,同时又提供了 unsafe 块赋予内核设计者操作底层硬件的能力。换言之,我们只需要保证将尽可能少的代码放在 unsafe 块,并保证这一小部分代码是内存安全的,那么经过 rustc 编译后的内核就是内存安全的。

关于 rCore

第一次与 rCore 结缘是在第七届“龙芯杯”大赛中,只不过那时遇到的是 rCore 的前身 uCore。

rCore 是 uCore 的 Rust 重构版本,而 uCore 参考了 XV6 的实现。从指令架构上来看,XV6 支持的是 x86,一种广泛使用的 CISC,但由于其闭源性、复杂性已经逐渐被教学所抛弃。uCore、rCore 面向的是以 RISCV 为代表的 RISC。RISC 最早提出是为了解决 CISC 指令间相关性难以判断的问题,两条 RISC 指令之间很容易判断相关性,从而实现流水线的微架构设计。

此次参加开源 OS 训练营,是我第一次学习 rCore。在学习过程中,我体会到了 rCore 是如何利用 Rust 语言的机制(特点)进行编写的。接下来我将举例总结。

cargo:Rust 的包管理、构建工具

相比于 C 语言等传统的系统级编程语言,Rust 提供了包管理和构建工具 cargo,好处是:

  1. 可以方便地引入一些库,为编写内核提供便利,无需重复造论子

    比如说在 ch3 中出现了一个 heap_alloc.rs 文件,他在里面创建了一个静态的 HEAP_ALLOCATOR,并使用 #[global_allocator] 进行了标记。后来在 ch4 的文档里我才理解它是用来进行(物理)堆内存分配的分配器,这样就能在内核里使用堆上数据了。而该分配器的具体实现则无需我们操心了,因为它是由一个名为 buddy_system_allocator 的 crate 提供的(结果上 crates.io 一查,是由 rcore-os 组织维护的一个库)。

  2. 构建过程更加简单
    理论上来说,构建一个 Rust 项目只需要 cargo build 就够了,但 rCore 实验还有其他需求,因此框架里使用了 Makefile。

所有权、生命周期

rCore 的内存管理系统巧妙地利用了 Rust 的所有权和声明周期机制。当申请了一个物理页时,分配函数 frame_alloc() 直接将物理页描述符 FrameTracker 的所有权返回,而这些页描述符的所有权直接被申请物理页的变量所拥有(如 PageTableMapArea)。当这些变量的声明周期结束时,他们所持有的 FrameTracker 的生命周期也将结束,而 rCore 为 FrameTracker 实现了 Drop trait,将在它们生命周期结束时“自动”回收物理页。