You are on page 1of 42

Modern

Operating System 4th 中译

目錄
1. Introduction
2. 译者前言
3. 前言
1. 前言
2. 关于作者
4. 1 简介
1. 1.1 什么是操作系统
1. 操作系统是一个扩展机
2. 操作系统是一个资源管理器
2. 1.2 操作系统的历史
1. 1.2.1 第一代(1945-55):电子管
2. 1.2.2 第二代(1955-65):晶体管及批处理系统
3. 1.2.3 第三代(1965-80):IC与多道编程
4. 1.2.4 第四代(1980-今):个人电脑
5. 1.2.5 第五代(1990-今):移动电脑
3. 1.3 计算机硬件回顾
1. 1.3.1 处理器
2. 1.3.2 内存
3. 1.3.3 磁盘
4. 1.3.4 I/O设备
5. 1.3.5 总线
6. 1.3.6 启动计算机
4. 1.4操作系统族谱
1. 1.4.1大型机操作系统
2. 1.4.2服务器操作系统
3. 1.4.3多处理器操作系统
4. 1.4.4个人计算机操作系统
5. 1.4.5掌上计算机操作系统
6. 1.4.6嵌入式操作系统
7. 1.4.7传感器节点操作系统
8. 1.4.8实时操作系统
9. 1.4.9智能卡操作系统

2
Modern Operating System 4th 中译

Introduction
Modern Operating System 4th 中译

这本书是 现代操作系统 第四版 的非官方中文翻译


This book is unofficial Chinese translation of *Modern Operating System 4th Edition*

MODERN OPERATING SYSTEMS


FOURTH EDITION
ANDREW S. TANENBAUM
HERBERT BOS

Vrije Universiteit
Amsterdam, The Netherlands

补充:近期家父住院翻译工作暂停,请谅解orz

15.8.20: 工作继续开始

Introduction 3
Modern Operating System 4th 中译

译者前言
Modern Operating System 4th 中译

这本书是 现代操作系统 第四版的非官方中文翻译。


译者仅为依兴趣自由翻译,保证尽量准确但是不保证绝对准确并且不对任何可能由此产生的后果负责。

This book is unofficial Chinese translation edition of book


*Modern Operating System 4th Edition*. The translator does not guarantee
the accuracy of the book and is not responsible for any sequence.

译者联系方式:lkwywhyc@gmail.com 或 lkwywhy@163.com
Contact translator at: lkwywhyc@gmail.com or lkwywhy@163.com

本书的名词尽量使用英文原文以保留原意。

译者前言 4
Modern Operating System 4th 中译

前言

前言 5
Modern Operating System 4th 中译

前言
前言
本书的第四版与第三版有很大的不同,众多变化不一一列举。为了给增加的内容提供空间并且避免本书的厚度变得难以控
制,多媒体系统的章节被移至Web。由于Windows Vista操作系统并没有像微软想象的那么成功,关于Windows Vista的章节也
被移除。并且由于Symbian不再流行,相关的章节也被从书内去除。Windows Vista的部分被Windows 8所取代,而Symbbian的
章节被Android所取代。另外新增了关于虚拟化和云的章节。以下是各章的概要。

第一章有大规模的更新改动,但是除了关于移动计算机的内容,没有主要章节被增加或者删除。
第二章对材料进行了更新,移除了老旧的内容并且增加了与时俱进的内容。比如我们增加了futex同步原语, 以及在
Read-Copy-Update操作时如何避免死锁。
第三章更多关注于现代硬件,同时分段以及MULTICS的比重下降。
在第四章我们移除了CD-Rom,原因是它们不再流行。同时使用更加现代的解决方案替换(比如闪存)。同时在RAID
小节中增加了RAID 6。
第五章有较大的变化,移除了CD-Rom,CRT等老旧设备,同时加入了触摸屏等新技术。
第六章变化不大,因为死锁这个话题本身并没有太多变化。加入了一些新内容。
第七章是全新的,主要内容为虚拟化和云。作为学习例程,加入了一节介绍VMware
第八章是之前多处理器系统的升级版。这个版本更多的关注于现在越来越重要的多核及众核系统。这一章也会包含越
来越明显的缓存一致性问题。
第九章经过了大量的修订,增加了关于bug利用,恶意软件以及它们的防御手段。同时空指针解引用(null pointer
dereference)以及缓冲区溢出(buffer overflow)也增加了更多细节。还增加了防御机制,比如canaries,NX bit及地址
空间随机化(address-space randomization)等,及其对策的详细介绍。
第十章经历了重大变化,Unix及Linux的相关内容被更新,并且加入了在智能手机及平板电脑上广泛使用的Android操
作系统。
第十一章由第三版中的Windows Vista更新到了Windows 8/8.1。
第十二章是之前版本第十三章的修订版。
第十三章是彻底更新的推荐读物列表。同时参考书目也被大规模更新。
为控制篇幅,原先版本的第七章被移至本书的网站。
此外,贯穿全书的Research部分被全部重做,以反映最新的操作系统研究。各章的课后习题也增加了新内容。

本书附有大量的学习资料,可以在 www.pearsonhighered.com/tanenbaum 获取。其中包含 PowerPoint幻灯片,学习操作系统所


需的软件工具,学生的实验,模拟器以及其他课程材料。使用本书的教员应当看一看。合作伙伴的网站为
www.pearsonhighered.com/tanenbaum 。网站部分内容被密码保护,需要使用注册。学生资源包括:

一个Multimedia Operating System的在线章节


实验室实验
在线练习
仿真练习

众多人员参与了第四版的写作,首先是合著者Prof. Herbert Bos of the Vrije University in Amsterdam。他是一名安全领域及Unix


领域的专家并且给予了很大帮助,他写了大量的新内容,除了以下列出的部分。

我们的编辑 Tracy Johnson 做了出色的工作,像往常一样,拼接项目,救火,并且保证项目进度。我们也有幸请回了我们的长


期编辑 Camille Trentacoste,她的技能大大节约了我们的时间。我们很高兴在阔别数年后再次合作。Carole Snyder在协调各路
人马上做的很棒。 第七章中关于VMware的部分(Sec. 7.12)由 Edouard Bugnion ,工作于Switzerland, Lausanne的EPFL,编
写。Edouard是VMware公司的创建者之一并且比世界上任何人都熟悉这份工作。对于他的慷慨帮助我们非常感谢。

Ada Gavrilovska of Geogia Tech, 一名Linux领域的专家,更新了她自己写的第三版的第十章。第十章的Android部分由Android


操作系统的核心开发者之一,于Google就职的 Dianne Hackborn 编写。Android是如今智能手机操作系统的领跑者,所以对于
Dianne的帮助我们十分感激。第十章非常长并且细节很多,但是UNIX,Linux以及Android粉们可以从中学到很多。这个可能
是本书中最长并且技术性最强的章节由两名女性编写,我们仅仅做了简单的工作。

我们也没有忘记Windows。就职于Microsoft的 Dave Probert 更新了第十一章,加入了Windows 8.1 。Dave非常清楚Windows并


且可以洞悉Microsoft设计的优劣。Windows粉一定会非常喜欢这一章。

因为有众多的专家作贡献,这本书明显要好得多。在这里我们再次对他们无价的帮助表示感谢。

我们也得到了几个评论家的帮助,他们帮忙阅读手稿并且指出其中的错误。他们是 Trudy Levine, Shivakant Mishra, Krishna


Sivalingam, 以及 Ken Wong。 Steve Armstrong 制作了本书的教员用的PowerPoint幻灯片。

通常情况下文字编辑和校对人员不会得到感谢,但是 Bob Lentz (文字编辑) 和 Joe Ruddick (校对人员)做了非常出色的工


作,Joe 可以在20m外指出Roman Period及Italic字体的区别。然而,作者对任何剩余的错误承担全部责任。读者若发现任何错
误都应当联系任一作者。

最后,但并非最不重要的,Barbara 和 Marvin 仍然是最棒的,各自有各自的个性。 Daniel 和 Matilde 是我们家庭的重要补


充。 Aron 和 Nathan 是非常棒的小伙子并且 Olivia 是个宝贝。当然,我要感谢 Suzanne 的爱和耐心,更不必说 Druiven ,
Kersen 和 Sinaasappelsap。

最重要的是,我必须感谢 Marieke, Duko 和 Jip。感谢 Marieke 的爱和对我连夜写作的容忍,感谢 Duko 和 Jip,让我知道生

前言 6
Modern Operating System 4th 中译

活中有更重要的事情。比如 Minecraft。

Andrew.S.Tanenbaum

Herbert Bos

前言 7
Modern Operating System 4th 中译

关于作者
To be finished

关于作者 8
Modern Operating System 4th 中译

1 简介
简介
一台现代计算机包括*1一个或更多的处理器,一些主存,磁盘,打印机,一个键盘,一只鼠标,一台显示器,网络接口,以
及其他的输入输出设备。总而言之,一个复杂的系统。如果一个普通的程序员都必须理解所有的设备如何工作,恐怕没有人
写的出任何代码。进一步说,管理众多设备并且高效地使用它们是一个非常有挑战性的工作。因此,计算机装有一层软件,
称为操作系统,为用户(普通程序员)提供更好,更简单,更简洁的计算机系统模型,并且负责管理之前提到的所有资源。
操作系统即为本书的主题。

大部分读者都使用过一些操作系统,比如Windows, Linux, FreeBSD, OS X,但是外表可以是迷惑性的。与用户交互的程序,


当基于文本时通常称之为shell,使用图标时一般称为GUI(Graphic User Interface)——读作“gooey”,事实上并不是操作系统
的一部分,尽管只有通过操作系统它才能完成它的工作。

Fig. 1-1是简单的结构图。硬件位于底层,包括芯片,电路板,磁盘,键盘,显示器,以及其他类似的器件。硬件层之上是软
件层。大部分电脑有两种操作模式:内核模式(kernel mode)和用户模式(user mode)。作为软件层最基础的部分,操作
系统运行在内核模式(又称为特权模式 supervisor mode*2)。这个模式下操作系统有所有硬件的访问权限并且可以执行任何
指令。其余的软件运行在用户模式,只能使用机器指令的子集。特别的,所有可能影响到计算机控制或者
I/O(Input/Output)的指令不能由用户模式的程序执行。我们将会反复讨论kernel mode与user mode的的区别,它在operating
system如何工作中起了重要作用。

与用户交互的程序,比如shell或者GUI,位于user mode软件的最底层。它们可以允许用户启动其他应用程序,比如Web浏览
器,E-mail阅读器,或者音乐播放器。这些程序也非常依赖于operating system。

Ooperating system的位置在Fig. 1-1中标明,它运行在纯硬件之上并且为其他软件提供服务。

Operating system与正常(user mode)应用程序的重要区别是,如果用户不喜欢自己的E-mail Reader,ta可以安装其他的程序


或者自己写一个作为替代。然而用户不能写他自己的时钟中断处理器*3,4,因为这是操作系统的一部分并且受硬件保护,用
户不能自行更改。

然而在一些嵌入式系统中(可能没有kernel mode),或者解释系统中(比如基于Java的系统,使用解释而不是硬件来分离组
件),这个重要区别可能会变得不甚清晰。

此外,在许多系统中有运行在user mode但是帮助系统或执行特权的程序。例如经常有程序帮助用户更改他们的密码。它并不
是操作系统的一部分,也不运行在kernel mode,但是显然它在执行一个敏感功能并且必须被格外保护。在一些系统中这种想
法走到了一个极端,以至于传统观念认为应当由operating system处理的部分功能(比如文件系统)运行在用户空间。这种系
统是难以划清界限的。运行在kernel mode的部分毫无疑问地属于operating system,然而一些运行在user mode的应用程序也可
以说是operating system的一部分,或者至少是与operating system密切相关。

Operating system与用户程序区别莫过于他们驻留在哪里。特别是它们巨大、复杂并且常驻内存。一个operating system(例如

1 简介 9
Modern Operating System 4th 中译

Windows或Linux)内核的源代码都在500万行的数量级*5。这代表每页纸打印50行,每卷1000页(比这本书大),打印所有
的内核代码需要100卷——足够塞满整个书架。想象一下你得到了一份维护一个operating system内核的工作,第一天老板带你
来到一书架代码前并且要求你掌握它。而这仅仅是内核,加入必要的共享库后可以突破7000万行,足够塞满10到20个书架。
并且还没有包括基本的应用软件(文件浏览器,播放器等)。

所以现在应该很清楚了,为什么operating systems的生命周期特别之长——它们特别难写,写过一个后,它的主人就不愿意丢
掉重写。相反,这样的operating system会使用很长时间。Windows 95/98/Me基本上是同一个operating system,Windows
NT/2000/XP/Vista/7是另一个不同的operating system。对用户来说他们看起来很像是因为Microsoft确信Windows
NT/2000/XP/Vista/7的图形界面与它要取代的系统很像,尤其是Windows 98 。但是Microsoft也有抛弃Winddows 98的非常棒的
理由,我们将会在讲Windows的Chap. 11回到这个话题。

除了Windows,在本书中我们会用到的其他主要例子是UNIX及其变体和克隆。它也已经发展了很多年,随着版本发展,
System V,Solaris和Free BSD也从原有的系统分支出去。Linux是个全新的代码库,即使它与UNIX很像并且与UNIX高度兼
容。本书中我们会使用UNIX,并且在Chap. 10中了解Linux。

在本章中我们会简要地接触一些operating system概念,包括它们是什么,它们有什么历史,它们的周边,一些基本观念和
operating system的结构。这里的重要话题将会在之后的章节深入讨论。

1:译者注:可能有其他配置比如多个显示器。

2:译者注:其他翻译,例如管态,管理员模式。

3:译者注:Clock Interrupt Handler,处理时钟中断。

4:译者注:在一些不完善的操作系统(比如DOS,或者一些全部程序均运行在同一个mode的嵌入式操作系统中)中依旧可
以由用户改变。然而不完善的操作系统不在本书讨论之列。

5:译者注:最新的Linux内核已突破1000万行。

1 简介 10
Modern Operating System 4th 中译

1.1 什么是操作系统
1.1 什么是操作系统
很难定义操作系统是什么,最接近的就是 操作系统是运行在kernel mode的软件——即使这样也不总是对的。问题的一部分原
因是操作系统执行两个基本不相干的功能:为程序员(以及应用程序)提供一个简洁的资源抽象集——而不是混乱的硬件,
并且管理这些硬件资源。取决于谁在发言,你有可能听到约一项功能或者更多。让我们都作些了解。

1.1 什么是操作系统 11
Modern Operating System 4th 中译

操作系统是一个扩展机
操作系统是一个扩展机*1
大部分计算机的架构(指令集,内存组织,I/O,总线结构)在机器语言层面看,是非常原始并且难以编程的,输入输出尤
甚。为了使这一点更具体,考虑下广泛使用的现代SATA(Serial ATA)硬盘,一本描述接口早期版本(By Anderson, 2007)
——包含使用磁盘的必要知识——长达450页。之后,SATA接口经过多次修订,变得比2007年的早期版本越来越复杂。很明
显的,没有任何理智的程序员会选择在硬件层面上处理磁盘。而是使用被称为磁盘驱动程序的软件处理磁盘,并且提供读写
磁盘块的界面,程序员不需要关心细节。操作系统包含许多处理I/O的驱动程序。

但是即使是这种水平,对于大部分程序来说还是太低级。因此,所有的操作系统都提供 文件 作为磁盘系统的另一层抽象。通
过这层抽象,程序可以创建,写入,读取文件,而不需要考虑硬件如何工作的混乱细节。

这种抽象是管理所有这类复杂性的关键。良好的抽象可以把一个几乎不可能完成的工作变成两个可管理的工作。首先是定义
并且实现抽象,第二步是通过抽象来解决手头的问题。之前提到的文件是几乎所有计算机用户都能够理解的抽象。它是一片
有用的信息,可能是照片,或者保存的E-mail,或者歌曲,或者网页。处理照片,E-mail,歌曲或者网页明显比处理
SATA(或者其他)磁盘要来的容易。操作系统的任务就是创建良好的抽象,然后实现并且管理由此产生的抽象对象。在这本
书,我们会讨论很多抽象,它们是理解操作系统的重点。

这一点是非常重要的,值得反复重复。对所有的设计Macintosh的工程师表示极高的尊敬。真实的硬件是丑陋的,真正的处理
器,内存,磁盘和其他设备非常复杂并且难以使用,对于程序员来说很难使用这些混乱并且不一致的接口。有时这是为了和
老旧硬件兼容,有时是纯粹为了省钱。然而,通常情况下硬件设计师并没有意识到(也许是不关心)他们给软件带来了多少
麻烦。操作系统的主要任务之一就是掩盖硬件丑陋的设计,向运行的程序(以及它们的程序员)提供一个漂亮,干净,优
雅,一致,抽象的接口。操作系统化丑陋为美丽,如图Fig. 1-2.

应当注意的是,操作系统真正的客户是应用程序(通过应用程序编写者)。它们是直接与操作系统及其抽象打交道的。与此
相反,终端用户处理用户界面提供的抽象,用户界面可能是一个命令行程序或者图形界面。虽然用户界面的抽象可能和操作
系统提供的抽象非常相似,但是这仅仅是特例。例如Windows的图形界面及命令提示符,二者均为Windows上的应用程序并且
使用了同样的抽象层,然而它们对用户提供的接口却风格迥异。与此相似的是,Linux用户使用的KDE或Gnome桌面环境尽管
运行在相同的抽象层之上,但是二者的体验区别也很大。

在这本书,我们将会深入研究提供给应用程序的抽象层的细节,而不是用户界面。这是一个庞大并且重要的主题,然而与操
作系统的联系不甚明显。

1:译者注:原文为Extended Machine,结合文意应当为扩展硬件系统之意,或者抽象机

操作系统是一个扩展机 12
Modern Operating System 4th 中译

操作系统是一个资源管理器
操作系统是一个资源管理器
以自上而下的视角看,操作系统为应用程序提供了抽象层。然而自下往上看,操作系统管理着复杂系统的各个细节。现代计
算机系统包含了处理器,内存,计时器,磁盘,鼠标,网络接口,打印机,以及其他各种各样的设备。在自下而上的视角
中,操作系统的工作就是面向众多的应用程序提供处理器,内存,I/O设备的有序分配。

现代操作系统允许多个程序同时驻留内存并且同时运行。想象一下如果某台计算机上的三个应用程序都试图同时在同一台打
印机上打印它们的输出会发生什么。最后有可能前几行输出来自于程序1,之后的几行来自程序2,下面几行来自程序3,以此
类推。最终的打印结果将变得混乱不堪。操作系统可以通过在磁盘上缓存同一台打印机的所有输出来保证有序的输出。当一
个程序结束,操作系统将它的输出从磁盘中取出,同时其他程序可以继续产生输出,即使输出并不会真的(立刻)送到打印
机。

当一台电脑(或者网络)有多个用户时,管理/保护内存,I/O设备以及其他资源的需求就变得非常迫切,因为用户可能以某
些方式干扰彼此。此外,用户经常需要共享硬件以外的东西,比如文件,数据库等。简而言之,这种对操作系统的认识认为
操作系统的主要工作是跟踪哪些软件在使用哪些硬件,保证资源请求,统计用量,调解不同的程序和用户之间相互冲突的请
求。

资源管理中的资源复用有两种方式:时间复用及空间复用。当资源被时间复用时,不同的程序或用户轮流使用。例如系统仅
有一个CPU然而需要运行多个程序,操作系统首先将CPU分配给第一个程序,在其运行足够长的时间后另一个程序得到CPU
使用权,之后是另一个,直到回到第一个程序。确定复用策略——谁下一个使用,使用多久——是操作系统的任务。另一个
时间复用的例子是打印机,当多个任务排队等待打印时,就需要决定下一个打印哪个。

另一种复用方式是空间复用。消费者并不轮流使用,而是每个消费者使用资源的一部分。例如,内存一般被分配给好几个正
在运行的程序,所以每个程序均可在内存驻留(比如在等待CPU)。假如内存足以容纳多个程序,同时容纳多个程序显然比
一次容纳一个程序高效得多,尤其是在每个程序仅需要内存的一小部分的情况下。当然,这会引起公平性,内存保护等问
题,并且应当由操作系统解决这些问题。另一个空间复用的资源是硬盘,许多系统中,一块磁盘可以同时保存来自多个用户
的众多文件。分配磁盘空间,跟踪区块的使用是一个操作系统的典型任务。

操作系统是一个资源管理器 13
Modern Operating System 4th 中译

1.2 操作系统的历史
操作系统的历史
操作系统已经进化多年。在下面的章节中我们将简要地看一下几个亮点。鉴于操作系统被紧紧地绑定在它所运行的架构之
上,我们将看看连续的几代计算机,了解它们操作系统的结构。这种在不同次代的操作系统与不同次代的计算机间建立的映
射虽然粗糙,但是它确实在提出结构方面有一些用处。

1.2 操作系统的历史 14
Modern Operating System 4th 中译

1.2.1 第一代(1945-55):电子管
第一代(1945-55):电子管
在Babbage失败的尝试之后*1,直到第二次世界大战,建造数字计算机的工作才取得些微进展。John Atanasoff教授及他的研究
生Clifford Berry在Iowa State Universiy建造了被认为是第一台有实用价值的数字计算机。它使用了300个电子管。几乎同时,
Konrad Zuse在Berlin使用继电器建造了Z3计算机。1994年,一组科学家(包括Alan Turing)在位于England的Bletchley公园建
造了the Colossus并且完成编程,Howard Aiken在Harvard建造了Mark I,William Mauchley和他的研究生J.Presper在University of
Pennsylvania建成了ENIAC。有些是二进制的,有些使用了真空管,还有些是可编程的,但是都非常原始并且做最简单的计算
都需要花费很长时间。

在这些早期的日子里,每台机器都需要单独的一组人员(通常是工程师)设计,建造,编程,操作,维护。所有的编程工作
都是通过机器语言完成,甚至更糟的情况是通过操作数千条电缆来控制机器的基本功能。编程语言是没有的(甚至没有汇编
语言),操作系统是闻所未闻的。通常的操作模式是程序员在墙上的表格上登记使用,回到机房将ta的插板插入计算机,在
接下来的几个小时中默默祈祷运行时20000多个真空管中不要有任何一个烧坏。几乎所有的问题都是简单明了的数学以及数值
计算,例如计算正弦,余弦,对数,或者计算炮弹轨迹。

到了20世纪50年代初,引入了有所改善的穿孔卡片。从此可以在卡片上写程序,然后由计算机读取。

1:译者注:此处应当是指Charles Babbage的分析机/差分机,被认为是计算机的先驱。 参考资料:


https://en.wikipedia.org/wiki/Charles_Babbage

1.2.1 第一代(1945-55):电子管 15
Modern Operating System 4th 中译

1.2.2 第二代(1955-65):晶体管及批处理系统
第二代(1955-65):晶体管及批处理系统
20世纪50年代中期诞生的晶体管使得这种窘境做出了极大的改变。计算机的可靠性增加到足以保证它们被生产出来,交付到
客户手中后满足客户的需求。这也是第一次将设计师,建造者,操作员,程序员以及维护人员分离。这些现在被称为大型机
的计算机,被锁在空调机房,由专业人员操作它们。只有大型企业或者政府机构承担的起它们几百万美元的售价。要运行一
个作业(一个程序或一个程序组),程序员先把程序写在纸上(使用FORTRAN或者汇编语言),之后将它们输出到卡片
上。然后将卡片带到输入室,把它交给操作员,之后去喝咖啡,直到得到程序的输出。

当计算机完成了它当前的工作,操作员把打印机上的输出撕下,放到输出室以便程序员收集。操作员再从输入室取出一叠卡
片,输入计算机,如此循环。如果程序需要FORTRAN编译器,操作员必须从文件柜中取出它,输入计算机。计算机的大部
分时间浪费在四处走动的操作员身上。

由于计算机高昂的价格,人们自然而然地寻找减少浪费时间的办法。广泛采取的解决方案是批处理系统,其背后的思想是尽
可能充满输入室,使用一台小的,不那么贵的计算机,如IBM1401,一台非常擅长读取卡片的计算机,从磁带将输出打印出
来。其他的一些昂贵的计算机,例如IBM7094,被用于真实环境,如图Fig, 1-3。

收集大概一小时的工作后,卡片的内容被读入磁带,再送入机房。操作员将磁带挂载到驱动器上,运行一个特殊的程序(当
今操作系统的祖先),读取磁带,运行第一个工作。输出内容被写入磁带,而不是直接打印。完成一项作业后,操作系统自
动载入下一项作业。整个批处理执行完毕后,操作员取走输入输出磁带,放入新的批处理磁带,再将输出磁带放到1401计算
机处离线打印(不连接至主计算机)。

一个典型的输入作业结构如图Fig. 1-4所示。作业由$JOB卡片开始,指定了以分钟计的最大运行时间,用户账户和程序员的名
字。之后的卡片是$FORTRAN,告诉操作系统从系统磁带中加载FORTRAN编译器。卡片之后直接跟着需要编译的程序。之
后的$LOAD卡片指导操作系统加载之前编译好的程序。(编译后的程序往往写在划伤的磁带所以必须被显式载入)之后是
$RUN卡片,告诉操作系统使用卡片之后的数据运行程序。最终$END卡片结束作业。这些原始的控制卡片是现代shell和命令
行解释器的先驱。

巨大的第二代计算机常常被用来做科学及工程计算,如求解物理及工程中经常出现的偏微分方程。它们经常使用FORTRAN
或者汇编语言编程。典型的操作系统是FMS(the Fortran Monitor System)以及IBSYS,IBM为7094计算机配备的操作系统。

1.2.2 第二代(1955-65):晶体管及批处理系统 16
Modern Operating System 4th 中译

1.2.3 第三代(1965-80):IC与多道编程
第三代(1965-80):IC与多道编程
在20世纪60年代,大多数计算机生产厂家有两道互不兼容的产品线。一方面,有面向字的,大规模科学计算机,如7094,被
用于在科学和工程工业强度数值计算。另一方面,有面向字符的商用计算机,如1401,被广泛用于银行和保险公司的磁带存
储、打印。

对计算机厂家来说,同时开发、维护两条完全不同的产品线是一个很大的负担。此外,许多计算机用户一开始需要一台小计
算机,但是渐渐地他们需要一台更大的计算机,可以运行以前的应用程序,但是更快。

IBM试图通过System/360来解决这些问题。360是从1401到更大机型的一系列软件兼容的机器。这些机器只有价格和性能(最
大内存,处理器速度,允许的I/O设备数量等等)的区别。因为它们有相同的架构和指令集,为一台机器编写的程序也可以运
行在其他机器上,至少理论上可以。(但是正如Yogi Berra所说:“在理论上,理论和实践没有区别。在实践上,他们有区
别”)因为360产品线被设计为既可以处理科学计算(如数值计算),也可以处理商业计算,同一个家族的产品可以满足所有
客户的需求。在随后的多年,IBM推出了向后兼容的360产品线的接班人,使用了更多的现代技术,被称为370,4300,
3080,以及3090。z系列是这条线的最近后裔,尽管和原来相比已经有了天壤之别。

IBM的360是主要计算机中第一个使用(小规模)IC(集成电路),从而在与普遍由独立晶体管制成的第二代计算机的竞争中
提供性价比优势。这是一个非常成功的决定。同时兼容产品线的思想也被各厂家接受。这些机器的后代现在依然被使用,通
常用于管理大型数据库(如机票预订系统)或者作高负载的web服务器。

单个产品线的最大优势恰恰也是它最大的软肋。所有的软件,包括操作系统,必须运行在所有可能的硬件之上。小至只是为
了替代1401系列,将卡片拷贝到磁带的机器,大至替代7094系列,用于做天气预报以及其他大规模计算的计算机。它必须能
够处理各种类型的设备,可以工作在商业环境或者科学环境。最重要的是,对于任何类型的客户,它都必须一样的可靠高
效。

很明显IBM(或者任何试图这么做的)并不能写出一套软件满足这些互相冲突的条件。其结果是一个极其巨大而复杂的系
统。可能有FMS代码数量级的两到三倍,由数千名程序员写的数百万行汇编代码组成,包含成千上万的bug,因此有必要在后
续的更新中修复。然而修复数个已有bug时引入了新的bug,所以很长一段时间内bug总数大致不变。

Fred Brooks,OS/360的设计者之一,随后写了一本诙谐精辟的书(Brooks,1995),描述了他开发OS/360的经历。尽管在本
书中总结它是不可能的,然而说明这个过程就像是一个深陷泥潭的怪兽。Silberschatz等人的文章也说明操作系统操作系统更
像是恐龙。

尽管其巨大的体积和繁多的问题,OS/360和与它类似的其他第三代操作系统还是满足了大部分客户的需求。与第二代操作系
统相比,它们还有众多的新功能。也许其中最重要的就是多道。在7094中,如果当前的作业等待磁带读取或者其他I/O操作,
CPU就必须停下等待操作完成。在重度依赖CPU的科学计算中,I/O操作并不频繁,所以问题还不明显。然而在商业应用中,
I/O等待占用了总时间的约90%,所以必须采取措施避免珍贵的CPU时间如此浪费。

解决方案是将内存分成数块,每块内存中放置一个作业,如图Fig. 1-5。当一项作业在等待I/O时,另外一个可以使用CPU。如
果一次可以在内存中加载足够的作业,CPU使用率可以接近100%。同时在内存中安全地运行多个作业需要配备特殊的硬件以
保护每项作业的内存空间免受其他作业的窥探。360以及其他第三代系统配备了这种硬件。

第三代操作系统另一个主要特点是可以在卡片被送到机房的时候就将程序读入磁盘。当一项作业完成后,操作系统就可以将
一项新的作业载入内存并且运行。这项技术被称为后台,也可以用于输出。用于输出时就不需要1401,也不需要反反复复搬
运磁带。

1.2.3 第三代(1965-80):IC与多道编程 17
Modern Operating System 4th 中译

尽管第三代操作系统非常适合大型科学计算以及海量商业数据处理,他们依然是基本的批处理系统。许多程序员还是念念不
忘第一代系统,他们可以完全操作计算机达数个小时,于是可以快速debug他们的程序。第三代操作系统中提交作业至获得输
出间的间隔通常长达数个小时,因此一个逗号放错可能导致编译失败,并且浪费程序员半天的时间。所以程序员并不非常喜
欢第三代操作系统。

这种对于快速响应的需求促成了分时系统(黑)的诞生。分时是多道编程的变种,每个用户有一个独立的在线终端。在分时
系统中,如果当前有20个用户登录,并且其中的17个用户都在思考人生或者高谈阔论或者喝咖啡,CPU就可以为另外3个用户
服务。因为程序员在debug时经常运行一些小命令(例如编译一个只有5页的程序)而不是大程序(例如排序一个上百行的文
件),所以计算机可以在为数量可观的用户提供快速的交互式服务时同时在CPU空闲时后台完成一个大型批处理作业。
CTSS(Compatible Time Sharing System,兼容分时系统)由MIT在一台特别改造的7094(Corbato ´ et al., 1962)上开发。然而
直到必要的保护硬件在第三代计算机中普及之后,分时系统才真正变得流行。

在CTSS系统的成功之后,MIT,贝尔实验室以及通用电气公司(当时还是一个主要的计算机生产商)下决心着手开发“计算
机服务”,即为一台可以同时支持上百个分时用户的计算机。就像是电力系统——当你需要电力时,只需要简简单单地插上插
头,就可以随意使用取之不竭的电力。这个系统名为MULTICS(MULTiplexd Information and Computer Service)。它的设计
师预见,当MULTICS建成,一台计算机即可提供整个Bostion所需的计算能力。这个建造一台比现有的GE-645主机快10000倍
的电脑的主意是纯纯粹粹的科学幻想,听起来就像是现在建造超音速跨大西洋海底隧道一样。

MULTICS在某些意义上也是成功的。它的设计致力于在一台仅比Intel 386 PC稍快的计算机上支持上百个用户,尽管它的IO更


强大一些。事实上这个目标并没有像它听起来一样疯狂,因为那时的人们擅长写短小而高效的程序,而现在的程序员已经逐
渐失去了这个技能。MULTICS没能接管世界是有很多原因的,不仅仅是因为它是由PL/I语言编写,而PL/.I编译器不仅姗姗来
迟而且极难正常工作,更因为MULTICS过分错误估计了它的时间——有点像18世纪Charles Babbage的分析机。

长话短说,MULTICS将许多开创性的想法引入了计算机文化,但是将这些开创性的想法转变成可用成熟的商业产品的难度是
超出任何人预料的。贝尔实验室退出了这个工程,之后通用电气也退出了计算机行业。然而MIT坚持了下来,并且逐渐推出
了可用的MULTICS版本。最终MULTICS被作为商业软件出售,全球总共有大约80家大公司和学校采用,销售方
(Honeywell)收购了通用电气的计算机部门。因为用户量少,所以MULTICS用户非常高贵。用户包括General Motors,
Ford,以及U.S. National Security Agency。其中的U.S. Security Agency更是在90年代才关闭了他们的MULTICS系统,那时离
MULTICS发布已经过去30多年了。

20世纪将结束之时,计算机应当被公用的观念已经开始落伍。当然这个想法可能会在云计算时代归来。在云计算时代,小的
计算终端(包括智能手机,平板电脑以及类似的设备)都被连接至远程的数据中心,计算任务由数据中心完成,而本地设备
仅负责与用户交互。这么做的动机是大部分用户不愿意管理越来越复杂琐碎的计算机系统,而更愿意将这些工作交给数据中
心运维等专业团队。电子商务公司已经在这个方向努力了。又例如许多公司使用多核心服务器运行电子邮箱服务端程序,接
受众多的小设备的连接,就非常像MULTICS的设计理念。

尽管没有取得商业成功,MULTICS还是对后世的操作系统(尤其是UNIX及其衍生的操作系统,如FreeBSD,Linux,iOS以及
Android)产生了重大影响。它产生了许多论文和书籍(Corbato etal., 1972; Corbato ´ and Vyssotsky, 1965; Daley and Dennis,
1968; Organick, 1972; and Saltzer, 1974),也有一个依然活跃的网站www.multicians.org,上面有关于这个系统,它的设计师以
及用户的许多信息。

第三代计算机的另一个显著发展就是微型计算机的增长,最开始是DEC于1961年推出的PDP-1计算机。PDP-1只有4K 18bit的
内存,但是每台机器售价达120000美元(低于7094价格的5%),尽管如此市场反应依旧极好。在特定的非数值计算任务中,
它的表现几乎和7094一样快,由此诞生了一个新行业。很快就催生了一系列的PDP机型(不像IBM家族,每代之间均不兼
容),直至PDP-11.

贝尔实验室一名工作于MULTICS项目的科学家Ken Thompson,随后找到了一台没人使用的PDP-7微机,并且决定写一个全新
的单用户版的MULTICS。他的成果最终发展为UNIX操作系统,广泛流行于学术界,政府机构以及众多的商业公司。

UNIX的历史在别的地方有介绍(如 Salus,1994)。这些故事会在第十章介绍。因为它的源代码可以轻易获得,众多组织开
发了他们自己的(互不兼容)的版本,局面变得混乱。其中两个主要版本是 System V,来自AT&T,以及 BSD(Berkeley
Software Distribution),来自University of California at Berkeley。它们各自也有许多变种。为了使得写UNIX通用程序成为可
能,IEEE制订了UNIX的通用标准,称为POSIX,大部分UNIX均支持这个标准。POSIX定义了一组UNIX必须支持的最小系
统调用接口。事实上,不只是UNIX,一些其他的操作系统也支持POSIX标准。

另外值得一提的是,在1987年,本书作者(译者注:Andrew.S.Tanenbaum)发布了一个小的UNIX克隆版,命名为MINIX,用
作教育目的。仅从功能上来讲,MINIX同UNIX很像,包括POSIX支持。之后原版发展到了MINIX 3,高度模块化并且致力于
提供高可靠性。它可以检测并且替换出错甚至崩溃的模块(比如I/O设备驱动)而不需要关机重启,甚至不需要干扰正在运行
的程序。它致力于提供非常高的可靠性和可用性。有专门的书籍描述它的内部实现并且也可以很容易得到它的源代码
(Tanenbaum and Woodhull, 2006)。MINIX 3系统也可以在www.minix3.org免费获取(包括源代码)。

MINIX的一个自由的生产版本(同教学版本相对)由一个(作者的)学生Linus Torvalds编写完成,称为Linux。这个系统直接
受MINIX的启发,并且支持MINIX的众多功能(例如 MINIX文件系统)。尽管经过许多人许多方式的改进,Linux与
MINIX,UNIX在底层架构上依旧有许多共同点。对Linux历史和开源运动感兴趣的读者可以阅读Glyn Moody(2011)的书。
本书关于UNIX的描述大多也适用于System V,MINIX,Linux以及其他的UNIX变体。

1.2.3 第三代(1965-80):IC与多道编程 18
Modern Operating System 4th 中译

1.2.4 第四代(1980-今):个人电脑
1.2.4 第四代(1980-今):个人电脑
随着LSI circuit(Large Scale Integration circuit,大规模集成电路)——芯片中一平方厘米的硅片上可以包含上千个晶体管——
的发展,个人电脑的时代来临了。在体系架构上,个人电脑(起初被称为微型计算机)与PDP-11等微机并没有太多不同,然
而价格区别很大。是个人电脑使得公司部门或大学可以有自己的电脑,微处理器芯片也令个人拥有电脑成为可能。

在1974年,当Intel推出8080,第一枚通用的8位CPU时,Intel想要一个8080运行的操作系统用于测试。Intel要求他们的顾问
Gary Kildall编写一个。Kildall和他的一个朋友一开始构建了一个新推出的8英寸软盘的驱动器并且连接到8080,由此产生了第
一台有磁盘的微机。Kildall之后写了一个基于磁盘的操作系统,称为CP/M(Control Program for Microcomputers)。由于Intel
不认为基于磁盘的微机有什么前途,当Kildall向Intel索要CP/M的版权时Intel答应了这个要求。Kildall之后成立了一家公司
Digital Research,专门开发销售CP/M。

在1977年,Digital Research重写了CP/M,使它可以运行在众多使用8080,Zilog Z80以及其他CPU芯片的微机之上。由于众多


程序均设计于CP/M系统上运行,所以CP/M完全统治了微机操作系统大约5年。

80年代初,IBM设计了IBM PC并且寻求可以运行的程序。IBM的人联系了Bill Gates,购买了他的BASIC解释器程序,并且询


问是否知道可以运行在PC上的操作系统。Gates向IBM推荐了Digital Research,几乎垄断的操作系统公司。然而Kildall拒绝同
IBM的人见面,指派他的下属来,使得这成为了有史以来最糟糕的一单生意。让事情变得更糟的是,他的律师甚至拒绝同
IBM签署关于尚未公布的PC的保密协议。于是IBM询问Gates是否可以为他们编写操作系统。

IBM的人走后,Gates意识到当地的一家计算机厂商Seattle Computer Products有一套合适的操作系统DOS(Disk Operating


System)。他提出购买DOS(据说只花了75000美元),Seattle Computer Products爽快地答应了。Gates向IBM提供DOS/BASIC
套装,IBM接受了。IBM想做一些更改,于是Gates雇佣了DOS的作者Tim Paterson到他的公司Microsoft做员工,完成这项工
作。改进后的系统被更名为MS-DOS(MicroSoft Disk Operating System)并且很快统治了IBM PC市场。一个关键因素是Gates
决定(现在看来非常明智)将MS-DOS卖给计算机厂家,与他们的硬件一同附送。与此相比,Kildall尝试将CP/M卖给终端用
户。在此之后,Kildall因为这些并没有完全公布的事情迅速而又意外地退出了竞争。

当IBM PC的继任者,IBM PC/AT于1983年推出,使用Intel 80286 CPU,MS-DOS的地位被进一步巩固,而CP/M在苟延残喘。


之后MS-DOS被广泛用于80386和80486。虽然MS-DOS起初的版本非常落后,但是其后期版本包含了众多的高级功能,其中许
多来自于UNIX。(Microsoft意识到了UNIX,甚至在公司早期销售过UNIX的微机版本,称为XENIX。)

早期的微机系统如CP/M,MS-DOS都基于用户从键盘敲击命令的方式。由于60年代 Stanford Research Institute 的Doug


Engelbart的工作,这种命令行交互逐渐改变。Engelbart发明了图形用户界面,由窗口,图标,菜单,鼠标组成。这些概念被
Xerox PARC的研究员采纳,并用于他们制造的计算机中。

有一天Steve Jobs,Apple computer的联合创始人之一,参观了PARC,看到了GUI,并且立刻意识到了它的商业价值,而这是


Xerox的管理层所没有意识到的。这个巨大的战略失误导致了一本书,题为摸索未来(Smith and Alexander, 1988)。Jobs随后
致力于为Apple开发GUI,最终造出了Lisa。Lisa太过昂贵以至于商业上并不成熟。Jobs的第二次尝试,Apple Macintosh,取得
了巨大的成功。不仅仅是因为它比Lisa便宜很多,更因为它对用户更加友好,这意味着它不仅仅是为了那些对电脑一无所知
的用户,更是为了那些丝毫无意学习的用户。在图形设计,专业摄影以及专业视频处理等创意市场,Macintosh使用非常广
泛,并且用户对此非常热心。在1999年,Apple使用了Carnegie Mellon University的Mach微内核,其设计目的是取代BSD
UNIX的内核。由此,Mac OS X成为了一个基于UNIX的操作系统,尽管有着非常独特的用户接口。

当Microsoft决定开发MS-DOS的继任者时,他们受到了Macintosh成功的强烈影响,开发了一个基于GUI的系统,称为
Windows。Windows起初运行在MS-DOS之上(相较于一个操作系统,它更像是一个shell)。从1985到1995的10年间,
Windows只是MS-DOS之上的一个图形界面。然而从1995年开始的一个Windows独立版本,Windows 95,包含了许多操作系统
的功能,仅用MS-DOS启动和运行老的MS-DOS程序。1998年,推出了这个系统的一个轻微修改的版本,称为Windows 98。
然而不论Windows 95还是Windows 98都包含了大量的16位Intel汇编代码。

另外一个Microsoft操作系统,Windows NT(这里的NT代表New Technology),在某种程度上兼容Windows 95,但是是从底层


重写的。Windows NT是一个完全32位的操作系统。Windows NT的首席设计师是David Cutler,同时也是VAX VMS操作系统的
设计师,所以VMS的一些理念也出现在NT。事实上因为VMS太多的特点出现在NT中,DEC指责Microsoft剽窃。此案最终花
费巨额资金达成庭外和解。Microsoft预计Windows NT的第一个版本将会淘汰MS-DOS和其他全部的Windows,因为NT拥有非
常强的技术优势,然而事实并非如此。只有Windows NT 4.0达成了这一点,尤其是在企业网络。1999年初,Windows NT的第
五版更名为Windows 2000,它的目的是继承Windows 98和Windows NT4.0。

这个策略也并不太成功,于是Microsoft推出了Windows 98的另一个版本,称为Windows ME(Millennium Edition,千禧版)。


2001年推出了Windows 2000的一个轻微升级的版本,称为Windows XP。这个版本工作了很长时间(6年),并且基本取代了
之前所有的Windows版本。

Windows之后继续推出新的版本。Windows 2000之后,Microsoft将Windows家族分为桌面版和服务器版两个产品线。桌面版即
为Windows XP及其继任者,服务器版包括Windows Server 2003及Windows Server 2008。嵌入式版作为第三条产品线出现的略
迟。所有的Windows均提供Service Pack形式的升级服务。这已经足以安慰一些系统管理员(以及操作系统教材作者)了。

之后直到2007年1月,Microsoft才发布了Windows XP的下一代产品,称为Windows Vista。Vista提供了全新的图形界面,增强


的安全性,以及众多全新或升级的应用程序。Microsoft期望它能够取代Windows XP,然而它究其一生也没有实现这一点。相
反,Windows Vista由于它极高的系统需求,严格的授权制度,以及支持数字版权保护,使得用户难以复制受保护的文件而饱
受批评。

1.2.4 第四代(1980-今):个人电脑 19
Modern Operating System 4th 中译

当Windows 7,一个全新并且系统需求没那么高的版本推出之后,许多人决定跳过Vista直接升级到Windows 7。Windows 7并


没有引入太多新功能,但是它相对来说比较小并且稳定。发布不到三周之后,Windows 7的市场份额就超过了Vista发布7个月
之后的份额。在2012年,Microsoft推出了新产品Windows 8,设计了全新的外观风格,并且针对触控做了专门优化。Microsoft
希望新的设计可以使Windows 8运行在诸多设备之上:桌面计算机,笔记本,上网本,平板电脑,手机,家庭影院等等,一统
天下。然而Windows 8的市场表现却赶不上Windows 7。

桌面计算机操作系统的另一个主要竞争者是UNIX(以及它众多的变体)。UNIX的强项在于网络和企业应用,但是也可以用
在桌面计算机,笔记本,平板电脑以及智能手机上。Linux作为Windows的替代品也在学生等群体中普及开来。

为简化说明,本书中会使用x86指代所有基于70年代8086指令集家族的现代处理器。这种类型的处理器很多,主要生产商是
Intel和AMD,二者有一定区别。处理器可能是32位也可能是64位,可能有很少或很多个核心,流水线可能很长也可能很短。
但是无论如何对程序员来说,它们看起来都差不多,并且都可以运行35年前写的8086代码。当区别很重要时我们将严格区分
它们——使用x86-32和x86-64分别指代32位和64位变种。

FreeBSD也是一个流行的UNIX变体,起源自Berkeley的BSD工程。所有的现代Macintosh均运行着定制的FreeBSD版本(OS
X)。UNIX在使用高性能RISC芯片的工作站上也几乎成为标配。它的变体也运行在多种移动设备上,比如运行iOS 7或者
Android的设备。

许多UNIX用户(尤其是有经验的程序员)相比于GUI更偏好于命令行式交互。所以几乎所有的UNIX都提供一套图形系统,
称为X Window System(X11),由M.I.T.研发。X负责基本的窗口管理,允许用户使用鼠标创建,关闭,移动以及改变窗体大
小。在X11之上一般运行着完整的GUI,比如Gnome或KDE。它们为喜欢GUI的UNIX用户提供类似于Macintosh或Microsoft
Windows的交互风格。

80年代中期发生的一个有趣变化是运行网络操作系统和分布式操作系统(Tanenbaum and Van Steen, 2007)的个人计算机网络


的增长。在一个网络操作系统中,用户可以发现同网络的其他计算机,可以登录远程计算机并且互相拷贝文件。每台计算机
均运行着本地的操作系统并且有本地用户。

网络操作系统与之前的单处理器操作系统并没有本质区别。很明显它们需要一个网络接口控制器和一些底层驱动软件提供类
似远程登陆和远程文件访问等服务。但是这并没有改变操作系统的骨架。

而一个分布式操作系统与此相反,它对用户表现为一个传统的操作系统,尽管其实它运行在多个处理器上。用户并不能意识
到他们的程序在哪里运行而文件又储存在哪里;这些细节应当交由操作系统自动高效完成。

真正的分布式操作系统不仅仅是传统的单处理器操作系统加几行代码那么简单,因为分布式和集中式系统有本质的不同。例
如分布式系统通常允许程序同时运行在多个处理器上,为了优化并行数量需要更为复杂的处理器调度算法。

另外,网络延迟通常意味着这些调度算法必须在数据不完整、不及时、甚至不正确的情况下运行。这个情况同单一处理器系
统,调度器拥有系统状态的完整信息完全不同。

1.2.4 第四代(1980-今):个人电脑 20
Modern Operating System 4th 中译

1.2.5 第五代(1990-今):移动电脑
1.2.5 第五代(1990-今):移动电脑
自从40年代漫画中的侦探Dick Tracy讲述他的“双向无线腕表”开始,人们就渴望拥有一个可以随身携带的通讯工具。第一部真
正的移动电话于1946年发明,有约40kg重。只要你有一辆车就可以带它到任何地方。

第一部真正意义上的手机出现在70年代,约1kg重,相对来说轻了很多。它有一个爱称“大哥大”。很快每个人都想拥有一
部“大哥大”。而如今移动电话用户覆盖了全球90%的人口。我们不仅仅可以用手机打电话,也可以用手表,未来的眼镜以及
其他穿戴设备。移动电话也可以做更多事情,我们可以收电邮,上网,发短信,玩游戏,导航,不能更美妙。

将电话和计算结合成一个设备的想法也出现在约70年代。但是第一部真正的智能手机出现在90年代中期,Nokia的N9000,革
命性地将电话和PDA(Personal Digital Assistant)结合起来。1997年,Ericsson为他们的GS88智能手机创造了一个名
字“Penelope”。

如今智能手机无所不在,而操作系统大战的结果甚至不如PC市场明朗。本书写作时,Google的Android统治了市场而Apple的
iOS占第二位,但是这不是定局,并且几年之内可能又有变化。如果智能手机市场还有什么是确定的,那就是没人知道谁是长
久的赢家。

简要来说,起初的十年间,智能手机大多运行着Symbian OS。尤其是Samsung,Sony,Motorola,Nokia等名牌。然而其他操
作系统,RIM的Blackberry OS(发布于2002年)和Apple的iOS(同第一部iPhone于2007年发布)开始蚕食Symbian的市场份
额。许多人认为RIM将会统治商务市场而iOS会成为消费市场的王者。Symbian的市场地位一落千丈。2011年Nokia放弃了
Symbian,宣布转到Windows Phone阵营。一段时间内Apple和RIM分享了整个市场(尽管并没有Symbian那样完全)。但是没
过多久,Android,一个Google于2008年推出的基于Linux的操作系统,就追赶上了它们。

对于手机厂家来说,Android有一个优势,那就是它是开源的,有很宽松的许可证。所以他们就可以轻松修改并且将Android
移至自家硬件上。另外Android也有庞大的开发者社区,大多使用Java语言。即便如此最近几年的情况显示Android的统治地位
可能不会持续太久,Android的竞争者迫切希望夺回它们的市场份额。我们将在10.8节介绍Android。

1.2.5 第五代(1990-今):移动电脑 21
Modern Operating System 4th 中译

1.3 计算机硬件回顾

1.3 计算机硬件回顾 22
Modern Operating System 4th 中译

1.3.1 处理器
1.3.1 处理器
计算机的“大脑”是CPU。CPU从内存中取出指令并执行它们。每个CPU的基本周期是从内存中取出第一条指令,解码确定其
操作数和类型,执行,如此循环直至程序结束。程序以这种方式运行。

每个处理器都有一组它可以执行的特定指令。因此一个x86 CPU不能执行ARM架构的程序,反之亦然。因为访存以获得指令
或数据比执行一个指令耗时更长,所有的CPU均包含一些寄存器以保存一些关键变量和临时结果。因此,指令集通常包含一
个从内存中加载一个字到指定寄存器的指令,和一个将寄存器中一个字写入到内存的指令。其他的指令将寄存器、存储器或
二者中的两个操作数处理得一个结果,例如求两个字的和,结果存入寄存器或主存。

除了用来保存变量和临时结果的通用寄存器,大多数计算机都有几个对程序员可见的特殊寄存器。其中一个是程序计数器
(Program Counter,PC),储存了下一条指令的地址。当这条指令被取走后,PC更新指向到下一条指令。

另一个寄存器是栈指针(Stack Pointer,SP),指向了当前内存栈的顶部。栈包含了每个已进入但尚未退出函数的数据。函
数的栈保存了输入参数,局部变量,以及不在寄存器中的临时变量。

还有一个寄存器是PSW(Program Status Word)。这个寄存器包含描述当前状态的bit,数据由当前指令,CPU优先级,模式


(内核或用户),以及其他的控制bit决定。用户程序通常可以读取整个PSW但是可能只能写其中的几个bit。

PSW在系统调用以及I/O中起重要作用。操作系统必须清楚所有的寄存器。当CPU时间复用时,操作系统经常会停止一个运行
的程序并且开始另一个。每次停止一个程序,操作系统必须保存所有的寄存器以便程序之后运行时恢复。

为提高性能,CPU设计者早已放弃了简单的一次取指,译码,执行一条指令的方式。许多现代CPU可以同时执行多个指令。
例如,一个CPU可能有单独的取指,解码和执行单元,所以当它执行指令n时,它可以同时译码指令n+1,并且取第n+2条指
令。这样的组织方式被称为流水线(pipeline)。图1-7(a)展示了一条三级流水线。通常情况下流水线都比较长。在大多数
流水线设计中,如果一条指令被取指,那么它就必须被执行,即使它也许只是一条条件跳转指令。流水线使得编译器作者和
操作系统作者非常头痛,因为它们暴露了底层的复杂性而且他们必须处理这种复杂性。

比流水线更先进的设计是超标量(superscalar)CPU,如图1-7(b)。在这个设计中有多个执行单元,如一个整数运算单
元,一个浮点运算单元,一个布尔运算单元。CPU一次取两条或者更多的指令,解码,储存至缓存直至它们可以执行。只要
有一个执行单元空闲,CPU就会遍历缓存查找是否有空闲的执行单元可以处理的指令。如果有就将这条指令交由其处理并移
出缓存。这意味着这样的设计中指令经常是被乱序执行的。重要的是由硬件保证执行结果与顺序执行的结果相同,但是正如
我们所见,额外的复杂度又强加给了操作系统。

正如之前所说,除了一些极简单的嵌入式CPU,大多数CPU均有两个状态,内核模式及用户模式。通常由PSW中的一位控制
模式。当运行于内核模式时,CPU可以执行指令集中的任何指令并且使用任何硬件功能。桌面计算机和服务器中的操作系统
一般运行在内核态,拥有访问硬件的全部权限。在嵌入式操作系统中,一部分运行在内核态,操作系统的剩余部分运行在用
户态。

用户程序总是运行在用户态,只可以使用指令集的子集。同时也不能执行涉及I/O以及内存保护的指令。当然更不能通过设置
PSW的相关bit进入内核态。

为获取操作系统的服务,用户程序必须产生一个系统调用。这将导致系统陷入内核并且调用操作系统。TRAP指令将从用户态
切换到内核态并且转到操作系统。操作完成后控制权返回用户程序。我们会在本章后面详解系统调用机制。目前暂时认为这
是一种从用户态到内核态的特殊调用过程。 (As a note on typography, we will use the lower-case Helvetica font to indicate system
calls in running text, like this: read. 此处为原书的字体约定)

值得一提的是,计算机除了执行系统调用会产生自陷以外还有别的指令。大多数的其他自陷都是由于硬件对特殊情况的警告
产生,如尝试除0或浮点数溢出。但是无论如何,只要发生了自陷,操作系统都会接管系统并且决定下一步要做什么。有时程
序必须因为产生错误被终止,有时错误可以被忽略(比如浮点数被设为0)。最后,当程序声明它想自行处理某些特定的异常

1.3.1 处理器 23
Modern Operating System 4th 中译

情况,控制权也会交还用户程序以任其自行处理。

多线程及多核心芯片
Moore定律表明芯片中的晶体管数目每18个月翻一番。这个“定律”并不是什么动量守恒一样的物理定律,而是Intel联合创始人
之一的Gordon Moore的观测经验。Moore定律已经生效了超过30年,并且有望继续保持10年。在那之后每个晶体管包含的原
子数目太少以至于量子效应开始显现,阻碍晶体管的进一步缩小。

越来越充裕的晶体管数目引发了一个问题:应该如何高效地组织它们?我们之前提到了一个方法:超标量体系架构,同时准
备多个功能单元。但是新工艺可以容纳的晶体管数目继续增加,一个很容易想到的办法就是增大CPU的缓存。这确实发生
了,可是增大缓存带来的收益也越来越少。

很明显,下一步就是不仅仅重复一些功能单元,而是重复一些控制逻辑。Intel的Pentium 4处理器增加了这些特性,称为多线
程或超线程(hyperthreading,Intel对其的称呼)。其他的一些CPU也有类似功能,包括SPARC,Power 5,Intel Xeon,和
Intel的Core家族。简要来说就是允许CPU同时保存两个不同线程的状态并且在其中做快速的纳秒级的切换(线程是一种轻量
级进程,细节将会在第二章讨论)。如果一个进程需要读取内存数据(这需要很多CPU周期),一个多线程CPU可以切换到
另外一个线程。但是多线程技术并不提供真正的并行处理。虽然只能同时运行一个线程,但是线程切换时间被减小到了纳秒
级。

多线程也为操作系统增加了麻烦,因为每一个线程在操作系统看来就是一个独立的CPU。假设一个系统有两个CPU,每个
CPU2个线程,那么操作系统将认为这是一个4CPU系统。如果系统当前仅两个进程,那么操作系统就有可能将所有的任务分
配到同一个CPU上而另一个CPU完全空闲。这种情况下的效率反倒是远远赶不上一个CPU一个线程了。

除了多线程,许多CPU芯片上都有4个,8个或者更多的完整核心。图1-8显示的多核心芯片包含了4个核心,每个都是独立的
处理器(缓存会在下面解释)。有些处理器,如Intel Xeon Phi和Tilera TilePro单块芯片上已包含了超过60个核心。充分使用核
心数目如此多的系统毫无疑问需要一个多核心操作系统。

顺便一提,说起绝对数量,没有什么芯片比得上现代GPU(Graphics Processing Unit)。一个现代GPU包含上千个小核心。


这样的结构非常擅长处理大量并行的小规模计算,例如图像程序中的渲染。但是它们不擅长串行的任务,也难以编程,尽量
GPU对操作系统来说很有用(例如加密或处理网络流量),但是操作系统本身运行在GPU上仍然不太可能。

1.3.1 处理器 24
Modern Operating System 4th 中译

1.3.2 内存
内存
计算机中第二重要的部分就是内存。理想情况下,内存应当足够快(应当比CPU执行任何指令都要快,这样CPU才不会受限
于内存),足够大并且相当便宜。然而目前还没有什么技术可以实现全部的目标,所以必须使用别的方法。内存系统是构建
在多层体系上的,如图1-9。最高层的主存有最高的速度,容量较小并且每bit价格最高。

最高层包括了CPU内部的寄存器。它们与CPU一同制造并且同CPU一样快,因此可以认为访问它们是没有延迟的。在32位
CPU中它们的典型容量是32x32bits,64位CPU中是64x64bits。无论如何都小于1KB。程序必须自行管理(例如决定它们用来
存什么)寄存器。

接下来是缓存,一般由硬件控制。主内存被分为缓存行(cache line),一般每行64bits,如地址0~63为line 0,64~127为line


1。使用量最大的行被调入接近CPU的高速缓存。当程序需要访存时,缓存硬件检查需要的行是否已经在缓存中。如果在,就
称为缓存命中(cahce hit),需要的数据可以直接送给CPU而不需要耗费大量时间通过内存总线访问主内存。由于价格高
昂,缓存大小也很有限。有些计算机有二级甚至三级缓存,每一级都比上一级更大但也更慢。

在计算机科学中缓存技术是非常重要的,不仅仅是内存的缓存。当一种资源可以被分割,并且其中一部分比另一部分使用的
概率更大,那么缓存技术就经常被用来提升性能。操作系统中经常用到类似技术。例如,多数操作系统在内存中保存着频繁
访问的文件(或者一部分)以避免一遍遍从硬盘读取。与此类似,长目录名,例如
/home/ast/projects/minix3/src/kernel/clock.c,到磁盘物理地址的转换结果,也被缓存到内存中以避免频繁的查询。最后,一个
WEB页面(URL)转换为网络地址(IP地址),结果也会被保存以未来使用。其他的用处不一一例举。

在任何一种缓存系统中,有几个问题很容易遇到,包括:

1. 何时将新的内容放入缓存。
2. 将新的内容放到缓存哪一位置。
3. 需要空闲空间时移除缓存中的哪一部分。
4. 缓存中赶出的数据放到主存的哪一部分。

并不是每一个问题都与任何缓存情况相关。对于主内存的CPU缓存,一般每产生一个缓存未命中,就会有新的内容进入缓
存。一般将要使用的缓存行是通过一些确定的内存地址引用比特计算出来的。例如4096 x 64的32位地址缓存中,位6至17可能
被用来指定缓存行,0~5比特是行内的比特。在这种情况下,将要移除的项和将要插入的项是同一个位置,但是在其他的系统
上则未必。最后,当修改后的数据重新写回主存时,就涉及到之前提到的回写地址的问题。

(待改进) Not every question is relevant to every caching situation. For caching lines of main memory in the CPU cache, a new item
will generally be entered on every cache miss. The cache line to use is generally computed by using some of the high-order bits of the
memory address referenced. For example, with 4096 cache lines of 64 bytes and 32 bit addresses, bits 6 through 17 might be used to
specify the cache line, with bits 0 to 5 the byte within the cache line. In this case, the item to remove is the same one as the new data
goes into, but in other systems it might not be. Finally, when a cache line is rewritten to main memory (if it has been modified since it
was cached), the place in memory to rewrite it to is uniquely determined by the address in question.

缓存对性能的提升如此之大,以至于现代CPU一般都有2个缓存。第一级缓存,或者说L1 Cache,总是在CPU内部并且通常为
CPU内部的执行引擎解码指令服务。多数CPU有第二个L1缓存,用于重度使用的数据。典型的L1大小是16KB。另外通常还有
一个二级缓存,称为L2 cache,保存着最近使用的内存中的几兆字节的数据。L1与L2时间上的区别是,访问L1缓存通常没有
延迟,然而访问L2缓存一般有一到两个时钟周期的延迟。

在多核心芯片中,设计师必须决定缓存应该放在哪里。在图1-8(a)中,只有一个L2缓存并且被所有核心共享。Intel的多核
心芯片通常采用这种方式*1。与此相反,如图1-8(b)所示,每个核心都有独立的二级缓存,这种方式通常被AMD采用。两
个策略各有优劣。例如,Intel的共享L2要求更复杂的缓存控制器但是AMD的方式使得保持L2的一致性变得更加困难。

1.3.2 内存 25
Modern Operating System 4th 中译

主内存在图1-9等级的下一层。这一层是内存系统中工作最重的。主内存一般被称为RAM(Random Access Memory,随机存


储器)。以前也被称为core memory,因为大约在50~60年代的计算机使用铁氧体磁芯作为主内存。磁芯内存早已消失但是称
呼还是留了下来。现在的内存一般有几百兆至几GB并且正在快速增长。所有CPU要求而不能放在缓存的数据均被放在主内
存。

除了主内存,许多计算机都有少量的非易失随机存储器。与RAM不同,非易失随机存储器中保存的数据断电后不会丢失。
ROM(Read Only Memory,只读存储器)通常在设备出厂时被编程并且内容不能更改。它读取很快并且并不昂贵。在一些
计算机中,启动所需的启动引导器(bootstrap loader)就被写在ROM中。同样的道理,一些I/O卡也自带ROM用于低级设备
控制。

EEPROM((Electrically Erasable PROM,电可擦写只读存储器)和Flash存储器也是非易失性的,但是与ROM不同的是它们


可以被擦除重写。然而相比于RAM,它们的擦写需要大量的时间,所以它们一般是和ROM一样的用途,只是在程序发现bug
时可以重写它们。

Flash也被经常用于便携电子设备的存储介质。它们可以在数码相机中存储照片视频,或者是在MP3中存储歌曲音乐。Flash的
速度介于RAM和磁盘之间。另外,与磁盘不同,Flash擦写次数过多就会磨损。

另外一种记忆体是CMOS,也是易失性存储。大多数计算机使用CMOS储存当前的时间。CMOS内存和计时时钟由一枚小电池
供电,所以即使计算机断电时钟依旧不会停止。CMOS内存也保存着一些配置参数,例如开机时应当从哪个磁盘启动。使用
CMOS的原因是CMOS内存极为省电,即使是计算机出厂配置的电池也可以工作数年。然而如果电池没电,计算机就像得了
老年痴呆一样遗忘它已记住数年的设置,例如从哪个磁盘启动等

*1:近年的Intel CPU每个核心均有独立的L1,L2缓存,所有核心共享L3缓存

1.3.2 内存 26
Modern Operating System 4th 中译

1.3.3 磁盘
磁盘
下一级的就是磁盘(硬盘)。磁盘存储的每bit价格价格比RAM便宜两个数量级,或者同等价格下容量比RAM大两个数量
级。唯一的问题是随机读取硬盘的数据用时大概比内存慢三个数量级。原因是磁盘是一个机械设备,如图1-10。

一个磁盘包含一个或更多的旋转的金属圆盘,转速是5400,7200,10800RPM或更高。一个磁头臂在金属盘上移动,就像老
式留声机一样。信息被写到圆盘上的一系列同心圆中。在任何给定位置,每个磁头可以读取的环形区域被称为磁道。所有恒
定位置的磁道组合起来就成为了柱面。

每条磁道均被划分为一些扇区,一般一个扇区512字节。现代磁盘的外圈磁道比内圈磁道有更多的扇区。磁头移动到相邻的柱
面需要大约1ms,移动到随机的柱面一般需要5~10ms,取决于设备。一旦磁头进入正确的磁道,驱动器必须等待要读取的扇
区旋转到磁头下,这又需要5~10ms,取决于磁盘的RPM。就绪后,低端磁盘的读取速度可以到大约50MB/s,快的可以达到
160MB/s。

有时,人们所说的磁盘并不是真正的磁盘,例如SSD(Solid State Disks,固态硬盘)。SSD没有移动部件,没有旋转磁盘,


将数据储存在Flash中。SSD与磁盘唯一的相似之处就是它们都存储了大量数据并且断电后不会丢失。

许多计算机支持被称为虚拟内存的技术,我们将会在第三章详述。这种技术通过将磁盘作为内存,内存作为频繁使用部分的
缓存使得程序可以使用比物理内存更大的内存空间。这项技术要求快速将程序的内存地址转换为物理地址。这项映射功能由
CPU的一部分提供,称为MMU(Memory Management Unit),如图1-6。

缓存和MMU的存在对性能产生了很大的影响。当从一个程序切换到另一个程序时,称为上下文切换(Context Switch),有
必要清空全部缓存并且更改MMU的寄存器。这些操作都是代价非常大的,并且程序员会尽力避免这种情况发生。之后我们会
见到这种情况。

1.3.3 磁盘 27
Modern Operating System 4th 中译

1.3.4 I/O设备
I/O设备
CPU和内存并不是操作系统必须管理的唯一资源。I/O设备也占了操作系统很大的比重。如图1-6,I/O设备通常包含两部分:
控制器和设备本身。控制器是一枚或一系列用于控制设备的芯片。它从操作系统接受命令,例如从设备读取数据,并且执行
它们。

许多情况下,设备的实际控制是非常复杂繁琐的,控制器的工作就是为操作系统提供一个简单(事实上仍然非常复杂)的接
口。例如磁盘控制器接收的命令可能是读取磁盘2的11206扇区。控制器必须将这个线性扇区地址转换成柱面,扇区,磁头。
由于外圈柱面比内圈有更多的扇区,以及某些坏扇区被重映射至其他扇区等,这个转换可能会非常复杂。之后控制器必须判
断当前磁头臂在哪个柱面,然后命令它移动到目标柱面。之后必须等待要读取的扇区旋转至磁头下,之后需要在它转离磁头
前完成读写和校验。最后将数据组合成字存入内存。为完成这些工作,控制器一般包含一个小的嵌入式计算机专门完成这项
工作。

另一部分是设备本身。设备的接口非常简单,一方面因为它们并不能做复杂的工作,另一方面也因为这是标准需要。后者非
常重要,这样一个SATA磁盘控制器就可以控制任何一个SATA磁盘。SATA代表Serial ATA,ATA代表AT Attachment。顺便一
提AT标准,这是IBM于1984年推出的第二代“Personal Computer Advanced Technology”,基于6MHz的80286处理器。我们从中
可以看出计算机厂商总喜欢在现有的缩略词上缝缝补补。我们也可以注意到一些形容词,比如“advanced”应当极其谨慎地使
用,否则30年后看起来就会非常愚蠢。

SATA是目前计算机磁盘接口的标准。因为真实的设备接口被控制器隐藏,所以操作系统看到的是控制器的接口,这可能和设
备本身的接口有很大区别。

因为每种控制器都是不一样的,所以就需要不同的软件负责和控制器交互,发送命令并且读取回复。这种软件称为设备驱动
(device driver)。每个控制器厂家都提供针对每个支持的操作系统的驱动。因此一台扫描仪可能有OS X,Windows 7,
Windows 8和Linux的驱动程序。

为使用驱动程序,它就必须被放入操作系统以运行在内核模式。事实上驱动程序也可以运行在内核外,操作系统如Linux和
Windows都对这种做法提供了一些支持,但是驱动的大部分依旧运行在内核。只有极少数的操作系统,例如MINIX 3,会把所
有的驱动程序运行在用户态。用户态的驱动程序必须有办法在受控的情况下访问硬件,这种方法并不简洁。

将驱动放入内核有三种方式。第一种办法就是将内核与新驱动程序重新链接,再重启系统。许多老旧的UNIX系统使用这种方
式。第二种是在操作系统中创建一个文件告诉系统需要一个新驱动,之后重启系统。在系统引导时,操作系统找到需要的驱
动程序并且载入它们。Windows采用这种方式。第三种方式是操作系统可以在运行时动态无缝安装新的驱动程序而无须重新
启动。尽管使用这种方式的不多但是现在正在逐渐普及。热插拔设备,例如USB或者IEEE 1394总线设备(下文将讨论)需要
操作系统有动态加载驱动的能力。

每个控制器都有一系列用于通讯的寄存器。例如,一个最简单的磁盘控制器有用于区分磁盘地址,内存地址,扇区数和方向
(读or写)的寄存器。如果需要激活控制器,驱动程序从操作系统处接受命令,翻译成合适的寄存器值并且写入设备寄存
器。所有的设备寄存器组成I/O接口空间,我们将会在第五章介绍。

在一些计算机中,设备寄存器被映射到操作系统的地址空间,这样访问它们就可以像访问普通内存一样。在这种计算机中不
需要特殊的I/O指令,并且用户程序可以通过不允许访问这些内存地址(例如,通过使用基地址和限制寄存器)的方式来禁止
其对硬件的访问。在另外的电脑上,设备寄存器被放在专门的I/O接口空间,每个寄存器都有专门的接口地址。在这些机器上
需要专门的IN和OUT指令允许驱动程序在内核态下访问寄存器。前者不需要专门的I/O指令但是耗费了一些地址空间,后者不
使用地址空间但是需要专门的指令。两种方式都被广泛采用。

输入输出任务有三种完成方式。最简单的办法是,当一个应用程序发起系统调用时,内核将其翻译为对合适驱动程序的调
用。之后驱动程序开始读写并且不停地查询操作是否完成(一般有专门的bit指示设备是否忙碌)。当I/O操作完成后,驱动程
序得到数据并且返回。之后操作系统将控制权返还调用程序。这种方式被称为忙等待(busy waiting)并且有很明显的缺点,
就是在操作完成之前会一直占用CPU。

第二种方式是驱动程序发起I/O,并且要求操作完成后给出中断信号。在驱动程序返回之前,操作系统阻塞调用程序,并且去
做别的事情。当控制器检测到传输完成后,它产生一个完成的中断。

在操作系统中,中断机制非常重要。因此我们有必要更详细解释一下。图1-11(a)显示了一个三步的I/O处理过程。第一步,
驱动程序通过写入设备寄存器告诉控制器需要做什么。之后控制器开始操作设备。第二步,控制器完成读取或写入工作之后
就会通过特定的总线发送信号给中断控制器。第三步,如果中断控制器可以接受中断(可能由于正在处理优先级更高的中断
而繁忙),它就会通过处理器的一个引脚通知CPU。在第四步,中断控制器告诉CPU产生中断的设备号,这样CPU可以知道
哪个设备产生了中断(可能同时运行着多个设备)。

1.3.4 I/O设备 28
Modern Operating System 4th 中译

当CPU决定处理中断时,当前的PC和PSW一般被压入当前的栈并且CPU进入内核模式。设备号可能被用于设备中断例程
(interrupt handler)内存地址的索引。这部分内存被称为中断向量(interrupt vector)。开始中断例程(产生中断设备的驱
动程序的一部分)后,它会移除栈中的PC和PSW并且保存它们,再查询设备状态。中断例程最终完成后,系统返回原来的用
户程序将要运行的指令。如图1-11(b)所示。

第三种I/O操作方式需要特定的硬件:一个DMA(Direct Memory Access)芯片,它可以不经CPU而控制内存与某些控制器间


的数据流。CPU设置好DMA芯片,设定好需要传送的比特数,涉及到的设备和内存地址和方向,之后就放任不管。DMA芯
片完成工作后产生一个中断,然后同上处理。DMA和I/O硬件会在第五章详述。

有时(事实上经常)中断可能在一个非常不合适的时间产生,例如,当另一个中断例程正在运行时。因此,CPU可以选择关
闭中断,之后再重新打开。中断关闭时,任何完成的设备不停地产生中断信号,但是直至CPU重新使能中断之前都不会得到
响应。如果中断关闭时多个设备请求中断,中断控制器就必须决定首先通过哪个,通常取决于每个设备所静态指定的优先
级。优先级高的设备最先得到响应,其他设备必须等待。

1.3.4 I/O设备 29
Modern Operating System 4th 中译

1.3.5 总线
总线
图1-6的组织方式多年来一般用于微型计算机,也用于原本的IBM PC。然而随着CPU和内存速度的增长,单总线(有时特指
IBM PC总线)处理所有的通讯越来越成为系统的瓶颈。必须采取措施改变这一现状。最终增加了新的总线以处理快速的I/O
设备和CPU内存之间的通讯。作为最终进化的结果,一个现代x86架构图看起来像是图1-12的样子。

这个系统有多种总线(例如缓存,内存,PCIe,PCI,USB,SATA和DMI),每个总线都有不同的速率和功能。操作系统必须能
够全部识别它们,这样才能配置管理。主总线是PCIe(Peripheral Component Interconnect Express)总线。

PCIe总线由Intel发明,作为老旧的PCI总线(原ISA,Industry Standard Architecture总线的继任者)的下一代产品,能够胜


任每秒数十Gb的传输速率,远优于前代PCI总线。并且与PCI总线有很多不同。直到2004年PCIe总线产生之前,大多数总线都
是并行总线并且由所有设备共享。共享总线意味着多个设备使用同样的线传送数据,因此当多个设备传输数据时需要仲裁器
来决定使用者。与此对比的是,PCIe总线是专用总线,点对点连接。传统PCI总线的并行架构意味着传送每个字都要使用多根
数据线。在标准的PCI总线中,数据由32条并行数据线传送。与此不同的是PCIe使用串行传输架构并且一次使用单个连接发送
报文,传送所有bit,称之为单个通道,就像网络包。这种方式更为简单,因为不需要等待32个bit同时到位。PCIe也可以使用
并行,同时使用多个通道传送。比如同时使用32条通道传送32个报文。随着网卡显卡等次要设备速度的提升,PCIe标准也每
3~5年升级一次。如PCIe2.0 16通道可以提供64Gb/s的带宽,升级到PCIe3.0后带宽将会*1翻倍,而未来的PCIe4.0将会再次翻
倍。

与此同时,我们依然有许多遗留的PCI标准的老旧设备。如图1-12,这些设备被装载在一个独立的集线器上。考虑到未来,有
可能所有的PCI设备都会挂载在另一个集线器,集线器再挂载在主集线器上,形成一个树状总线。

在这种配置中,CPU通过快速的DDR3总线直接同内存通讯,通过PCIe同外部图形卡通讯,其余设备通过DMI(Direct
Memory Interface)总线连接的集线器通讯。集线器通过USB(Universal Serial Bus)总线连接USB设备,通过SATA总线连接磁
盘和DVD驱动器,PCIe总线连接以太网卡。还有我们提到的老旧的PCI设备,通过传统的PCI总线连接。

另外,每个核心都有独立的缓存和更大的共享缓存。这些缓存通过独立的总线连接。

USB发明的主要目的就是连接众多的低速I/O设备,例如键盘和鼠标。然而,称USB3.0总线达5Gbps的速度“慢”也许和第一代
IBM PC只有8Mbps的ISA总线相比不太相称。USB使用4根或8根(取决于版本)连线的小型连接器,同时为USB设备提供电
源和接地。USB是一种集中式总线,根设备每隔1ms就查询所有的设备是否有数据传输。USB1.0合计带宽为12Mbps,USB2.0
将它提升到了480Mbps,USB3.0进一步提升到了5Gbps。任何USB设备在连接到计算机后可以立刻工作而不需要重新启动。相
比于USB出现之前的设备,这一点令用户非常欣慰。

1.3.5 总线 30
Modern Operating System 4th 中译

SCSI(Small Computer System Interface)总线是为快速磁盘,扫描仪以及其他需要可观带宽的设备制定的高性能总线。这


些设备多数出现在服务器和工作站上。它们最高可以运行在640MB/s。

为合理使用图1-12所示的架构,操作系统必须了解所有连接的外围设备并且配置它们。这个需求促使Intel和Microsoft设计了
称为即插即用(plug and play)的PC系统,基于首先由Apple Macintosh提出的观念。在即插即用之前,每个I/O卡都有一个指
定的中断等级和固定的I/O寄存器地址。例如键盘是中断1,I/O地址从0x60到0x64,软驱控制器使用中断6,I/O地址为
0x3F0~0x3F7,打印机使用中断7,I/O地址为0x378到0x37A,等等。

一切看起来很美好,然而当用户买了一块声卡和一块网卡不凑巧地都使用中断号4时,麻烦就来了。他们会互相冲突并且任何
一个都不能正常工作。解决方案是在板卡上安装拨码开关或者跳线,要求用户设置一个互不冲突的中断和I/O地址。对于那些
致力于研究复杂PC的青少年来说也许不会设置错误,然而其他人的设置可能就会变成一团糟。

即插即用所做的就是系统自动收集所有I/O设备的信息,之后指定各个设备的中断和I/O地址,然后通知各设备。这个机制和
计算机启动有密切关系,所以我们应当了解一下,它并不是无关紧要。

*1:本书翻译时PCIe3.0标准已经推出

1.3.5 总线 31
Modern Operating System 4th 中译

1.3.6 启动计算机
启动计算机
启动过程简述如下。每台PC上都有一块主板(motherboard),在主板上有被称为BIOS(Basic Input Output System)的程
序。BIOS包含有低级的I/O软件,包括读取键盘,写屏幕,读写磁盘等等程序。现代主板一般将这些程序保存在一块Flash
上,在BIOS程序中发现bug时可以升级。

当计算机启动时,BIOS程序首先运行。它首先查询计算机安装了多少内存,检测键盘和其他基本设备有没有安装并且正常工
作。BIOS通过扫描PCIe和PCI总线完成这项工作。如果当前设备状况同上次启动不同,就需要配置新设备。

接下来BIOS通过尝试在CMOS中储存的启动顺序决定启动设备。用户可以在启动时进入BIOS设置来更改这项设定。一般来
说,BIOS会首先尝试从CD-ROM(或USB)设备启动,如果有的话。如果这一步失败,系统从硬盘启动。启动设备的第一扇
区被载入内存并且执行。这个扇区的程序会检测扇区最后的分区表,查找活动分区。之后第二级引导器从活动分区加载。这
个引导器负责引导操作系统。

之后操作系统从BIOS处获取配置信息。遍历每个设备,查询是否有设备驱动。如果没有则要求用户插入存有驱动的CD-
ROM(由硬件厂商提供)或者从Internet上下载。当操作系统获得所有的驱动程序后就会将它们载入内核。之后创建需要的后
台进程,启动登录程序或GUI。

1.3.6 启动计算机 32
Modern Operating System 4th 中译

1.4操作系统族谱
操作系统族谱
操作系统已经出现了过半个世纪。这么久的时间,操作系统产生了众多的类型,其中有些类型并不是为人所熟知。这一节我
们将会针对其中的9种作简要介绍,并且会在本书后面部分详细讲到它们。

1.4操作系统族谱 33
Modern Operating System 4th 中译

1.4.1大型机操作系统
大型机操作系统
在高端的是大型机的操作系统,这些有一个房间大小的大型机依旧可以在一些大公司的数据中心找到。在I/O能力上大型机和
个人电脑有着天壤之别。一台大型机拥有1000块磁盘,上百GB的数据也不奇怪;然而一台个人计算机有如此多的设备就不太
正常了。有时大型机也用来做高端web服务器,为一些大型电子商务站点和B2B业务提供服务。

大型机的操作系统为同时运行多项工作而深度定制,其中的大多数都需要巨量的I/O。它们通常提供三种类型的服务:批处
理,事务处理和分时。批处理是指一次处理多个工作而不需要与用户交互。

保险公司的请求处理以及连锁商店的销售报告一般来说是由批处理完成的。事务处理系统处理大规模的小请求,如检查银行
记录或者机票余量。每个请求都不会耗费太多资源,但是系统必须一秒内处理成百上千的请求。分时系统允许多个远程用户
同时运行任务,例如查询一个很大的数据库。这些功能关系比较明显;大型机操作系统一般同时扮演这几种角色。一个大型
机操作系统的例子是OS/390,是OS/360的后继产品。然而大型机操作系统在逐渐被UNIX变体,如Linux所取代。

1.4.1大型机操作系统 34
Modern Operating System 4th 中译

1.4.2服务器操作系统
服务器操作系统
下一级的是服务器操作系统。它们运行在服务器之上。服务器包含小至非常大的个人电脑,大至大型机的各种机器。它们通
过互联网一次服务多个用户,为其提供软件和硬件资源。服务器可以提供打印服务,文件服务或者Web服务。网络服务提供
商运行着许多服务器,为消费者提供服务,网站使用服务器保存网页并且处理客户的请求。经典的服务器操作系统有
Solaris,FreeBSD,Linux和Windows Server 201x。

1.4.2服务器操作系统 35
Modern Operating System 4th 中译

1.4.3多处理器操作系统
多处理器操作系统
为获得更大的总计算能力,一个越来越普遍的做法就是将多个CPU接入一个系统。取决于CPU如何连接以及共享了哪些资
源,这些系统被称为并行计算,多机或者多处理器。它们需要特别的操作系统,但是一般采用服务器操作系统,并且做了一
些在通讯,互联和持久性上的改进。

随着近期个人计算机多核心芯片的发展,就连传统笔记本和上网本操作系统也开始处理多处理器问题,并且核心数量似乎会
随时间继续增长。幸运的是,在多处理器操作系统多年研究所积累的知识可以很容易应用到多核心系统中。麻烦的地方在于
让应用程序充分使用计算资源。许多流行的操作系统,包括Windows和Linux都可以运行在多处理器之上。

1.4.3多处理器操作系统 36
Modern Operating System 4th 中译

1.4.4个人计算机操作系统
个人计算机操作系统
下一类是个人计算机操作系统。现代的个人计算机操作系统都支持多道编程,启动时一般会启动许多程序。它们的工作是为
单一用户提供很好的支持。它们被普遍用于文字处理,电子表格,游戏以及互联网接入。典型的有Linux,FreeBSD,
Windows 7,Windows8和Apple的OS X。个人计算机操作系统广为人知,以至于似乎根本不需要怎么介绍。事实上,许多人甚
至没有意识到其他类型操作系统的存在。

1.4.4个人计算机操作系统 37
Modern Operating System 4th 中译

1.4.5掌上计算机操作系统
掌上计算机操作系统
随着提及的系统变得越来越小,下一步就是平板电脑,智能手机和其他掌上设备。掌上计算机,最初是PDA(Personal Digital
Assistant),是一台可以放在手上操作的小型计算机。智能手机和平板电脑是最出名的例子。正如我们所见,目前这个市场
由Google的Android和Apple的iOS所统治,但是有很多潜在竞争者。多数设备夸耀它们的多核CPU,GPS,相机和其他传感
器,数量可观的内存以及精心设计的操作系统。此外它们都有海量的第三方应用程序(apps)为它们做更多的功能扩展。

1.4.5掌上计算机操作系统 38
Modern Operating System 4th 中译

1.4.6嵌入式操作系统
嵌入式操作系统
嵌入式系统运行在控制计算机中,通常不被认为是计算机并且不允许用户自行安装软件。

典型的例子是微波炉,电视机,汽车,DVD,旧式电话和MP3播放器。嵌入式系统与掌上系统主要的区别属性是未经信任的
程序不能够运行。

例如,你不能为你的微波炉下载新的程序——所有的软件都存储在ROM中。这意味着不需要在应用程序之间做保护,这大大
简化了系统设计。这个领域中流行的有Embedded Linux,QNX和VxWorks。

1.4.6嵌入式操作系统 39
Modern Operating System 4th 中译

1.4.7传感器节点操作系统
传感器节点操作系统
传感器网络的部署有很大的意义。每个节点都是一个微型计算机,它们彼此交流并且通过无线通信与基站联系。传感器网络
可以用来保护建筑物外围,守卫国境线,检测森林火灾,为天气预报提供数据,在战场上收集敌军行动等等。

每个传感器都是一台小型计算机,由电池提供能量并且有内建的无线电。它们电能有限,然而必须尽可能在户外工作很长一
段时间。工作环境通常很糟糕。因此网络必须足够健壮,能够接受个别节点的失效。尤其是在电池将要耗尽时,节点失效的
频率将会骤然升高。

每个节点都是一台有CPU,有RAM有ROM的计算机,一般还有几个传感器。它们运行的操作系统一般由事件驱动,响应外界
事件或者周期性测量,时间来源于内部时钟。操作系统必须小而简单,因为单一节点的RAM很小,并且电池寿命也是一个问
题。另外与嵌入式操作系统相似的是,所有的程序一开始就全部加载,并且用户不能运行从网络上下载的应用程序,这使得
设计简单了许多。TinyOS是一个著名的传感器节点操作系统。

1.4.7传感器节点操作系统 40
Modern Operating System 4th 中译

1.4.8实时操作系统
实时操作系统
另外一种操作系统是实时操作系统(Real Time Operating System)。这类系统设计时就充分考虑了响应时间。例如在工业过
程控制系统中,实时计算机就必须收集生产进度并且由此控制工厂的机器。这类型任务一般都有严格的时限要求。例如当一
辆车在流水线上移动时,特定的步骤必须在指定时间前完成。如果焊接机器人的焊接太早或太晚,那么就会毁掉产品。若响
应必须在一个指定时间内发生(或指定的时间范围),我们称之为硬实时(hard real-time)系统。这类系统多应用在工业过
程控制,航空航天,军工等类似的环境。硬实时系统必须保证在确定的时间做出正确的动作。

软实时(soft real-time)系统并没有严格的响应时间。在这种应用环境中,轻微的失时是可接受的,不会导致永久损坏等不
可接受的后果。数字多媒体系统就是一个典型案例。智能手机也是一个软实时系统。

因为硬实时系统必须满足严格的响应时间要求,有时操作系统就只是一个简简单单同应用程序链接在一起的库,结构紧凑并
且系统之间没有保护。这种实时操作系统的一个例子是eCos。

手持系统,嵌入式系统和实时系统的概念是部分重合的。基本所有的这些系统都汲取了一部分软实时系统的观念。嵌入式和
实时系统只运行由系统设计者植入的程序,用户不能自行添加,这在某些程度上降低了保护的压力。嵌入式和手持式系统主
要是针对消费用户,而实时系统更多偏向于工业应用。但是无论如何,它们确实有很多共同点。

1.4.8实时操作系统 41
Modern Operating System 4th 中译

1.4.9智能卡操作系统
智能卡操作系统
最小的操作系统运行在智能卡上。智能卡只有信用卡大小,藏有一块CPU芯片。它们的计算能力极其有限,内存也极小。有
的智能卡通过同读卡器的连接获取电力,但是非接触智能卡是无线供电的,这更加限制了它们的功能。有的卡片只有单一的
功能,例如电子支付,但是另外一些就可以同时具备多个功能。它们一般运行着私有的操作系统。

有些智能卡是Java驱动的,这意味着智能卡的ROM可以储存一个Java虚拟机(Java Virtual Machine,JVM)解释器。Java应


用程序被下载至智能卡,再由JVM解释器解释执行。有一些更强大的卡可以同时运行多个Java程序,由此产生了对调度的需
要。资源的管理和分配在同时运行多个程序时也成了一个明显的问题。这个问题一般交由智能卡上的操作系统(一般极其原
始)解决。

1.4.9智能卡操作系统 42

You might also like