为何要写这本操作系统书

现在国内外已有一系列优秀的操作系统教材,例如 William Stallings 的《Operating Systems Internals and Design Principles》,Avi Silberschatz 、 Peter Baer Galvin 和 Greg Gagne 的《Operating System Concepts》, Remzi H. Arpaci-Dusseau 和 Andrea C. Arpaci-Dusseau 的《Operating Systems: Three Easy Pieces》等。 然而,从我们自 2000 年以来的教学实践来看,某些经典教材对操作系统的概念和原理很重视,但还有如下一些问题有待改进:

  • 原理与实践脱节:缺乏在操作系统的概念/原理与操作系统的设计/实现之间建立联系的桥梁,导致学生发现操作系统实现相关的实验 与操作系统的概念相比,有较大的鸿沟。

  • 缺少历史发展的脉络:操作系统的概念和原理是从实际操作系统设计与实现过程中,从无到有逐步演进而产生的,有其发展的历史渊源 和规律。但目前的大部分教材只提及当前主流操作系统的概念和原理,有“凭空出现”的感觉,学生并不知道这些内容出现的前因后果。

  • 忽视硬件细节或用复杂硬件:很多教材忽视或抽象硬件细节,使得操作系统概念难以落地。部分教材把 x86 作为操作系统实验的硬件 参考平台,缺乏对当前快速发展的 RISC-V 等体系结构的实验支持,使得学生在操作系统实验中可能需要花较大代价了解相对繁杂的 x86 硬件细节,影响操作系统实验的效果。

这些问题增加了学生学习和掌握操作系统的难度。我们想通过尝试解决上面三个问题,来缓解学生学习操作系统的压力,提升他们的兴趣,让他们能够在一个学期内比较好地掌握操作系统。为应对“原理与实践脱节”的问题,我们强调了实践先行,实践引领原理的理念。MIT 教授 Frans Kaashoek 等师生设计实现了基于 UNIX v6 的 xv6 教学操作系统用于每年的本科操作系统课的实验中,并在课程讲解中把原理和实验结合起来,在国际上得到了广泛的认可。这些都给了我们很好的启发,经过十多年的实践,对一个计算机专业的本科生而言,设计实现一个操作系统(包括CPU)有挑战但可行,前提是实际操作系统要小巧并能体现操作系统的核心思想。这样就能够让学生加深对操作系统原理和概念的理解,能让操作系统原理和概念落地。

为应对“缺少历史发展的脉络”的问题,我们重新设计操作系统实验和教学内容,按照操作系统的历史发展过程来建立多个相对独立的小实验,每个实验体现了操作系统的一个微缩的历史,并从中归纳总结出操作系统相关的概念与原理,并在教学中引导学生理解这些概念和原理是如何一步一步演进的。

为应对“忽视硬件细节或用复杂硬件”的问题,我们在硬件(x86, ARM, MIPS, RISC-V 等)和编程语言(C, C++, Go, Rust 等)选择方面进行了多年尝试。在 2017 年引入了 RISC-V 架构作为操作系统实验的硬件环境,在 2018 年引入 Rust 编程语言作为开发操作系统的编程语言,使得学生以相对较小的开发和调试代价能够用 Rust 语言编写运行在 RISC-V 上的操作系统。我们简化了形象化、可视化操作系统的概念和原理的过程,目的是让学生可以把操作系统的概念和原理直接对应到程序代码、硬件规范和操作系统的实际执行中,加强学生对操作系统内涵的实际体验和感受。

所以本书的目标是以简洁的 RISC-V 架构为底层硬件基础,根据上层应用从小到大的需求,按 OS 发展的历史脉络,逐步讲解如何设计并实现满足这些需求的“从小到大”的多个“小”操作系统,并在设计实现操作系统的过程中,逐步解析操作系统各种概念与原理的知识点,对应的做到有“理”可循和有“码”可查,最终让读者通过主动的操作系统设计与实现来深入地掌握操作系统的概念与原理。

在具体撰写过程中,第零章是对操作系统的一个概述,让读者对操作系统的历史、定义、特征等概念上有一个大致的了解。后面的每个章节体现了操作系统的一个微缩的历史发展过程,即从对应用由简到繁的支持的角度出发,每章会讲解如何设计一个可运行应用的操作系统,满足应用的阶段性需求。从而读者可以通过对应配套的操作系统设计实验,了解如何从一个微不足道的“小”操作系统,根据应用需求,添加或增强操作系统功能,逐步形成一个类似 UNIX 的相对完善的“小”操作系统。每一步都小到足以让人感觉到易于掌控,而在每一步结束时,你都有一个可以工作的“小”操作系统。另外,通过足够详尽的测试程序,可以随时验证读者实现的操作系统在每次更新后是否正常工作。由于实验的代码规模和实现复杂度在一个逐步递增的可控范围内,读者可以结合对应于操作系统设计实验的进一步的原理讲解,来建立操作系统概念原理和实际实现的对应关系,从而能够通过操作系统实验的实践过程来加强对理论概念的理解,通过理论概念来进一步指导操作系统实验的实现与改进。

在你开始阅读与实践本书讲解的内容之前,你需要决定用什么编程语言来完成操作系统实验。你可以用任何你喜欢的编程语言和你喜欢的CPU上来实现操作系统。我们推荐的编程语言是 Rust ,我们推荐的架构是 RISC-V。

注解

目前常见的操作系统内核都是基于 C 语言的,为何要推荐 Rust 语言?

  • 事实上, C 语言就是为写 UNIX 而诞生的。Dennis Ritchie 和 KenThompson 没有期望设计一种新语言能帮助高效简洁地开发复杂的应用业务逻辑,只是希望用一种简洁的方式来代替难以使用的汇编语言抽象出计算机的行为,便于编写控制计算机硬件的操作系统。

  • C 语言的指针既是天使又是魔鬼。它灵活且易于使用,但语言本身几乎不保证安全性,且缺少有效的并发支持。这导致内存和并发漏洞成为当前基于 C 开发的主流操作系统的噩梦。

  • Rust 语言具有与 C 一样的硬件控制能力,且大大强化了安全编程。从某种角度上看,新出现的 Rust 语言的核心目标是解决 C 的短板,取代 C 。所以用 Rust 写 OS 具有很好的开发和运行的体验。

  • 用 Rust 写 OS 的代价仅仅是学会用 Rust 编程。

目前常见的指令集架构是 x86 和 ARM ,为何要推荐 RISC-V ?

  • 目前为止最常见的架构是 x86 和 ARM ,他们已广泛应用在服务器,台式机,移动终端和很多嵌入式系统中。它们需要支持非常多的软件系统和应用需求,导致它们越来越复杂。

  • x86 后向兼容的策略确保了它的江湖地位,但导致其丢不掉很多已经比较过时的硬件设计,让操作系统疲于适配这些硬件特征。

  • x86 和 ARM 在商业上都很成功,其广泛使用使得其 CPU 硬件逻辑越来越复杂,且不够开放,不能改变,不是开源的,提高了操作系统开发者的学习难度。

  • 从某种角度上看,新出现的 RISC-V 的核心目标是灵活适应未来的 AIoT 场景,保证基本功能,提供可配置的扩展功能。其开源特征使得学生都可以方便地设计一个 RISC-V CPU。

  • 写面向 RISC-V 的 OS 的代价仅仅是你了解 RISC-V 的 Supervisor 特权模式,知道 OS 在 Supervisor 特权模式下的控制能力。