跳转至

常见问题及解答

实验设计问题

相较于 CPP,本实验设计为什么选择 Rust 语言?

这部分内容的重点是“重复造轮子”的问题,其所指的并不是指操作系统的设计,否则有 Linux 了就没必要开发其他 OS Kernel 了,而更多指对于底层的封装和抽象、语言的支持等。

  1. 不需要为架构无关的数据结构“造轮子”

    在 CPP 的实现中,std 库与系统底层架构强耦合,在裸操作系统中无法使用,因此就连 vector 这类架构无关的数据结构都需要自己实现;在 rust 中,这些架构无关的代码被放在了 corealloc 两个底层包中,因此可以直接使用诸如 VecString 这些数据结构和相关功能。

  2. 不需要为数据格式化等杂项“造轮子”

    在 CPP 的实现中,比如 printf 的格式化实现是不透明的,想要重写的话就需要修改其源代码,而阅读 std 的头文件、源代码对于大部分人来说都是比较灾难性的体验;而在 rust 中,当我们为一个结构体实现了 Write trait (类似于接口)后,就天然的实现了 write_fmt 这些功能,可以直接利用现有的语言体系进行格式化输出

  3. 不需要为堆内存分配的兼容性“造轮子”

    在 CPP 的实现中,vector 底层使用的 malloc 函数无法直接替换和修改,这也是无法直接使用的核心原因;在 rust 中,内存分配的底层操作是被抽象的,只需要借助 #[global_allocator] 声明堆分配器,就可以为裸操作系统带来动态内存分配的能力,这一内存分配可以直接使用现有的实现,实际代码不到十行,带来的效果是开发基本与非裸机一致,可以使用全部诸如 Box 等特性,也为同学们未来可能的项目开发累积使用经验。

虽然从语言方面,Rust 带来的内存安全和新颖的语言设计概念都是值得学习的,对后续无论是编译原理还是现代特性理解都有帮助。但客观来说,Rust 学习也存在很高的门槛,虽然在实验设计中准备了很多的缓冲和学习机会,但还是需同学们自己进行权衡。

本实验设计与 rCore 实验设计的差异?

THU 的 rCore 课程实验是一个非常优秀的操作系统课程设计,它的设计目标是让学生能够从零开始,了解操作系统的各个部分,包括内核、驱动、文件系统、网络等等。

根据笔者 2021 年起步编写此操作系统的初期调研,riscv 的相关底层指令集、数据结构封装的质量上都和同时期的 x86_64 的 Rust 库有一定差距,同时还有高质量的 Writing an OS in Rust 博客和已经进行了一些探索的学长的项目做背书,因此在设计上选择了 x86_64 作为目标平台。

同时,也希望让学生能够在较短的时间内,通过现代化的工程化手段,了解操作系统的基本原理,并能够理解自己的电脑运行,掌握一定的”维修能力“,因此在设计上选择了更多的现代化工程化手段,如 UEFI 引导、FAT 文件系统等。

在 2024 年重新翻阅时,发现 riscv 的生态已经有了很大的进步,但是由于从实验初期就选择了架构强耦合路线:即为了避免过高的实现难度和“造轮子”,不考虑多架构支持,所以仍然保留 x86_64 的设计。

如果需要进行多架构支持,需要对页表、寄存器、控制等内容进行抽象和统一,这部分的工程化抽象开销会很大的增加学生的学习成本。

为什么选择基于 UEFI 而不是自己使用汇编编写 bootloader?

汇编是一种非常底层的语言,对于大部分同学的学习经历来说,只在组成原理课程上接触过简单的 MIPS / RISC-V,而 x86 / ARM 基本接触很少。根据以往的经验,汇编的调试、编写、理解对于同学们都是很大的挑战。

因此在设计层面希望能够减少汇编的使用,利用现有的运行环境框架如 UEFI,结合可以直接编译成 UEFI 可执行文件的 Rust 语言,达成这一目的。

同时,相对于以往面向于 x86 的方案首先需要手动处理从 16 位到 32 位的切换这一历史遗留问题,从指令集和操作系统层面,这都造成了对于过时设计的非必要的学习成本,在本就不长的实验周期中无形减少学生学到的知识份额。

实验实践问题

面对多种实验方案,该如何选择?

对于学校提供的多种实验方案,笔者秉持鼓励尝试,自行选择的态度。

但是在选择实验方案时,需要考虑到教师的要求和切换实验的成本:在 Lab 3(第四次实验)开始前,如果想要切换还有机会;如果实现到进程相关的内容,由于没有前期的铺垫和学习,再切换实验带来的成本就比较大了。