Skip to content

Commit

Permalink
update ch1-8:0
Browse files Browse the repository at this point in the history
  • Loading branch information
chyyuu committed Nov 7, 2021
1 parent 3c52911 commit 7caf187
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 16 deletions.
6 changes: 3 additions & 3 deletions source/chapter0/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ Remzi H. Arpaci-Dusseau 和 Andrea C. Arpaci-Dusseau 的《Operating Systems: Th
然而,从我们自 2000 年以来的教学实践来看,某些经典教材对操作系统的概念和原理很重视,但还有如下一些问题有待改进:

- 原理与实践脱节:缺乏在“**操作系统的原理与概念**”和“**操作系统的设计与实现**”之间建立关联关系的桥梁,二者有较大的鸿沟。这导致学生在做操作系统实现的实验过程中,难以与课堂上老师讲解的操作系统基本概念对应起来。
- 缺少历史发展的脉络:操作系统的概念和原理是从实际操作系统设计与实现过程中,随着硬件和应用需求的变化,从无到有逐步演进而产生的,有其发展的历史渊源和规律。但目前的大部分教材只提及当前主流操作系统的概念和原理,有“凭空出现”的感觉,学生并不知道这些内容出现的前因后果。
- 缺少历史发展的脉络:操作系统的概念和原理是从实际操作系统设计与实现过程中,随着硬件和应用需求的变化,从无到有逐步演进而产生的,有其发展的历史渊源和规律。但目前的大部分教材只提及当前主流操作系统的概念和原理,有“凭空出现”的感觉,学生并不知道这些内容出现的前因后果,只知道“How”,而不知道“Why”
- 忽视硬件细节或用复杂硬件:很多教材忽视或抽象硬件细节,使得操作系统概念难以落地,学生了解不到软硬件是如何具体协同运行的。部分教材把 x86 作为操作系统实验的硬件参考平台,缺乏对当前快速发展的 RISC-V 等体系结构的实验支持,使得学生在操作系统实验中可能需要花较大代价了解相对繁杂的 x86 硬件细节,编程容易产生缺陷(bug),影响操作系统实验的效果,以及对操作系统核心概念的掌握。

这些问题增加了学生学习和掌握操作系统的难度。我们尝试通过如下方法来解决上面三个问题,达到缓解学生的学习压力,提升他们的兴趣,能在一个学期内比较好地掌握操作系统的目标。

具体而言,为应对“原理与实践脱节”的问题,我们强调了实践先行,实践引领原理的理念。MIT 教授 Frans Kaashoek 等师生设计实现了基于 UNIX v6 的 xv6 教学操作系统用于每年的本科操作系统课的实验中,并在课程讲解中把原理和实验结合起来,在国际上得到了广泛的认可,也给了我们很好的启发。经过十多年的操作系统教学工作,我们认为:对一位计算机专业的本科生而言,设计实现一个操作系统(包括CPU)有挑战但可行,前提是这样的操作系统要简洁小巧,能体现操作系统中最基本的核心思想,并能把操作系统各主要部分的原理与概念关联起来,形成一个整体。这样就能够让学生加深对操作系统原理和概念的理解,能让操作系统原理和概念落地。

为应对“缺少历史发展的脉络”的问题,我们重新设计操作系统实验和教学内容,按照操作系统的历史发展过程来建立多个相对独立的小实验,每个实验是一个独立的操作系统,体现了操作系统的一个微缩的历史,并可从中归纳总结出操作系统相关的概念与原理,并在教学中引导学生理解这些概念和原理是如何一步一步演进的。表面上看,这样会要求学生了解多个不同的操作系统,增加了学生的学习负担。但其实每个实验中的操作系统都是在前一个实验的操作系统上的渐进式扩展,学生只需理解差异的部分,且学生通过不同操作系统的对比,可以更加深入地理解相关操作系统原理的前因后果。
为应对“缺少历史发展的脉络”的问题,我们重新设计操作系统实验和教学内容,按照操作系统的历史发展过程来设立每一章的内容,每一章会围绕操作系统支持应用的某个核心目标来展开,形成相应的知识点和具体实践内容。同时建立与每章配套的多个逐步递进且相对独立的小实验,每个实验是一个独立的操作系统,体现了操作系统的一个微缩的发展历史,并可从中归纳总结出操作系统相关的概念与原理。这样可以在教学中引导学生理解操作系统的这些概念和原理是如何一步一步演进的。表面上看,这样会要求学生了解多个不同的操作系统,增加了学生的学习负担。但其实每个实验中的操作系统都是在前一个实验的操作系统上的渐进式扩展,学生只需理解差异的部分,且学生通过分析不同操作系统对应用支持能力和对应实现上的差异,可以更加深入地理解相关操作系统原理的前因后果。

为应对“忽视硬件细节或用复杂硬件”的问题,我们在硬件(x86, ARM, MIPS, RISC-V 等)和编程语言(C, C++, Go, Rust 等)选择方面进行了多年尝试。在 2017 年把 复杂 x86 架构换为 简洁 RISC-V 架构,作为操作系统实验的硬件环境,降低了学生学习硬件细节的负担。在 2018 年引入 Rust 编程语言作为开发操作系统的可选编程语言之一,减少了用C语言编程出现较多运行时缺陷的情况。使得学生以相对较小的开发和调试代价进行操作系统实验。同时,我们把操作系统的概念和原理直接对应到程序代码、硬件规范和操作系统的实际执行中,加强学生对操作系统内涵的实际体验和感受。

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

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

Expand Down
2 changes: 1 addition & 1 deletion source/chapter1/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
这是注释:我觉得需要给出执行环境(EE),Task,...等的描述。
并且有一个图,展示这些概念的关系。
本章展现了操作系统的一个基本功能:让应用与硬件隔离,简化了应用访问硬件的难度和复杂性。这也是远古操作系统雏形和现代的一些简单嵌入式操作系统的主要功能。具有这样功能的操作系统的形态就是一个函数库,可以被应用访问,并通过函数库的函数来访问硬件。
本章展现了操作系统的一个基本目标:让应用与硬件隔离,简化了应用访问硬件的难度和复杂性。这也是远古操作系统雏形和现代的一些简单嵌入式操作系统的主要功能。具有这样功能的操作系统的形态就是一个函数库,可以被应用访问,并通过函数库的函数来访问硬件。

大多数程序员的第一行代码都从 ``Hello, world!`` 开始,当我们满怀着好奇心在编辑器内键入仅仅数个字节,再经过几行命令编译(靠的是编译器)、运行(靠的是操作系统),终于在黑洞洞的终端窗口中看到期望中的结果的时候,一扇通往编程世界的大门已经打开。在本章第一节 :doc:`1app-ee-platform` 中,可以看到用Rust语言编写的非常简单的“Hello, world”应用程序是如何被进一步拆解和分析的。

Expand Down
2 changes: 1 addition & 1 deletion source/chapter2/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
..
chyyuu:有一个ascii图,画出我们做的OS。
本章从一个更底层的角度来思考如何设计应用程序,并进一步展现了操作系统相关的一系列新功能
保障系统安全和多应用支持是操作系统的两个核心目标,本章从这两个目标出发,思考如何设计应用程序,并进一步展现了操作系统的一系列新功能

- 构造包含操作系统内核和多个应用程序的单一执行程序
- 通过批处理支持多个程序的自动加载和运行
Expand Down
4 changes: 2 additions & 2 deletions source/chapter3/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
chyyuu:有一个ascii图,画出我们做的OS。

本章展现了操作系统一系列功能
提高系统的性能和效率是操作系统的核心目标之一,本章展现了操作系统在性能上的一系列功能改进

- 通过提前加载应用程序到内存,减少应用程序切换开销
- 通过协作机制支持程序主动放弃处理器,提高系统执行效率
- 通抢占机制支持程序被动放弃处理器,提高不同程序对处理器资源使用的公平性,也进一步提高了应用对I/O事件的响应效率


上一章,我们实现了一个简单的批处理系统。首先,它能够自动按照顺序加载并运行序列中的每一个应用,当一个应用运行结束之后无需操作员的手动替换;另一方面,在硬件提供的特权级机制的帮助下,运行在更高特权级的它不会受到有意或者无意出错的应用的影响,可以全方位监控运行在用户态特权级的应用的执行,一旦应用越过了硬件所设置特权级界限或主动申请获得操作系统的服务,就会触发 Trap 并进入到批处理系统中进行处理。无论原因是应用出错或是应用声明自己执行完毕,批处理系统都只需要加载序列中的下一个应用并进入执行。可以看到批处理系统的特性是:在内存中同一时间最多只需驻留一个应用。这是因为只有当一个应用出错或退出之后,批处理系统才会去将另一个应用加载到相同的一块内存区域。
上一章,我们实现了一个安全的批处理系统。首先,它能够自动按照顺序加载并运行序列中的每一个应用,当一个应用运行结束之后无需操作员的手动替换;另一方面,在硬件级特权隔离机制的帮助下,运行在更高特权级的它不会受到有意或者无意出错的应用的影响;在硬件异常触发机制的帮助下,可以全方位监控运行在用户态的应用的执行,一旦应用越过了特权级界限或主动申请获得操作系统的服务,就会触发 Trap 并进入到批处理系统中进行处理。无论原因是应用出错或是应用声明自己执行完毕,批处理系统都只需要加载序列中的下一个应用并进入执行。可以看到批处理系统的特性是:在内存中同一时间最多只需驻留一个应用。这是因为只有当一个应用出错或退出之后,批处理系统才会去将另一个应用加载到相同的一块内存区域。

而计算机硬件在快速发展,内存容量在逐渐增大,处理器的速度也在增加,外设IO性能方面的进展不大。这就使得以往内存只能放下一个程序的情况得到很大改善,但处理器的空闲程度加大了。于是科学家就开始考虑在内存中尽量同时驻留多个应用,这样处理器的利用率就会提高。但只有一个程序执行完毕后或主动放弃执行,处理器才能执行另外一个程序。这种运行方式称为 **多道程序** 。

Expand Down
4 changes: 2 additions & 2 deletions source/chapter4/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
chyyuu:有一个ascii图,画出我们做的OS。

本章展现了操作系统一系列功能
物理内存是操作系统需要管理的一个重要资源,让运行在一台机器上的多个应用程序不用“争抢”,都能随时得到想要的任意多的内存,是操作系统的“理想”。提高系统物理内存的动态使用效率,通过隔离应用的物理内存空间保证应用间的安全性,把“有限”物理内存变成“无限”虚拟内存,是操作系统的一系列重要的目标,本章展现了操作系统为实现“理想”而要扩展的一系列功能

- 通过动态内存分配,提高了应用程序对内存的动态使用效率
- 通过页表的虚实内存映射机制,简化了编译器对应用的地址空间设置
- 通过页表的虚实内存映射机制,加强了应用之间,应用与内核之间的内存隔离,增强了系统安全
- 通过页表的虚实内存映射机制,可以实现空分复用(提出,但没有实现)

而且本章会进一步设计与实现具有上述功能的侏罗纪“头甲龙” [#tutus]_ 操作系统,让应用开发更加简单,应用程序更加通用,且让应用和操作系统都有强大的地址空间隔离的安全保护。
本章将进一步设计与实现具有上述大部分功能的侏罗纪“头甲龙” [#tutus]_ 操作系统,让应用开发更加简单,应用程序更加通用,且让应用和操作系统都有强大的地址空间隔离的安全保护。

.. _term-illusion:
.. _term-time-division-multiplexing:
Expand Down
6 changes: 4 additions & 2 deletions source/chapter5/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
本章导读
-------------------------------------------

在正式开始这一章的介绍之前,我们很高兴告诉读者:在前面的章节中基本涵盖了一个功能相对完善的内核抽象所需的所有硬件机制,而从本章开始我们所做的主要是一些软件上的工作,这会略微轻松一些。
在正式开始这一章的介绍之前,我们很高兴告诉读者:在前面的章节中基本涵盖了一个功能相对完善的操作系统内核所需的核心硬件机制:中断、特权级、页表,而且我们的应用程序在开发方面也越来越便捷了。但开发者的需求是无穷的,开发者希望能够在操作系统启动后,能灵活选择执行某个程序,但我们目前实现的操作系统还无法支持这样的功能。这说明操作系统还缺少对应用程序动态执行的灵活性和交互性的支持!

在前面的章节中,随着应用的需求逐渐变得复杂,作为其执行环境的内核也需要在硬件提供的相关机制的支持之下努力为应用提供更多强大、易用且安全的抽象。让我们先来简单回顾一下:
到目前为止,操作系统启动后,能运行完它管理所有的应用程序。但在整个执行过程中,应用程序是被动地被操作系统加载运行,开发者与操作系统之间没有交互,开发者与应用程序之间没有交互,应用程序不能控制其它应用的执行。这使得开发者不能灵活地选择执行某个程序。为了方便开发者灵活执行程序,本章要完成的操作系统的核心目标是: **让开发者能够控制程序的运行** 。

在前面的章节中,随着应用的需求逐渐变得复杂,作为其执行环境的操作系统内核也需要在硬件提供的相关机制的支持之下努力为应用提供更多强大、易用且安全的抽象。让我们先来简单回顾一下:

- 第一章《RV64 裸机应用》中,由于我们从始至终只需运行一个应用,这时我们的内核看起来只是一个 **函数库** ,它会对应用的执行环境进行初始化,包括设置函数调用栈的位置使得应用能够正确使用内存。此外,它还将 SBI 接口函数进行了封装使得应用更容易使用这些功能。
- 第二章《批处理系统》中,我们需要自动加载并执行一个固定序列内的多个应用,当一个应用出错或者正常退出之后则切换到下一个。为了让这个流程能够稳定进行而不至于被某个应用的错误所破坏,内核需要借助硬件提供的 **特权级机制** 将应用代码放在 U 特权级执行,并对它的行为进行限制。一旦应用出现错误或者请求一些只有内核才能提供的服务时,控制权会移交给内核并对该 **Trap** 进行处理。
Expand Down
Loading

0 comments on commit 7caf187

Please sign in to comment.