第1章 引论

现代计算机系统由一个或多个处理器、主存、磁盘、打印机、键盘、鼠标、显示器、网络接口以及各种其他输入/输出设备组成。一般而言,现代计算机系统是一个复杂的系统。如果每位应用程序员都不得不掌握系统所有的细节,那就不可能再编写代码了。而且,管理所有这些部件并加以优化使用,是一件挑战性极强的工作。所以,计算机安装了一层软件,称为操作系统,它的任务是为用户程序提供一个更好、更简单、更清晰的计算机模型,并管理刚才提到的所有这些设备。本书的主题就是操作系统。

多数读者都会对诸如Windows、Linux、FreeBSD或Mac OS X等某个操作系统有些体验,但表面现象是会骗人的。用户与之交互的程序,基于文本的通常称为shell,而基于图标的则称为图形用户界面(Graphical User Interface,GUI),它们实际上并不是操作系统的一部分,尽管这些程序使用操作系统来完成工作。

图1-1给出了在这里所讨论主要部件的一个简化视图。图的底部是硬件。硬件包括芯片、电路板、磁盘、键盘、显示器以及类似的设备。在硬件的顶部是软件。多数计算机有两种运行模式:内核态和用户态。软件中最基础的部分是操作系统,它运行在内核态(也称为管态、核心态)。在这个模式中,操作系统具有对所有硬件的完全访问权,可以执行机器能够运行的任何指令。软件的其余部分运行在用户态下。在用户态下,只使用了机器指令中的一个子集。特别地,那些会影响机器的控制或可进行I/O(输入/输出)操作的指令,在用户态中的程序里是禁止的。在本书中,我们会不断地讨论内核态和用户态之间的差别。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

用户接口程序,shell或者GUI,处于用户态程序中的最低层次,允许用户运行其他程序,诸如Web浏览器、电子邮件阅读器或音乐播放器等。这些程序也大量使用操作系统。

操作系统所在的位置如图1-1所示。它运行在裸机之上,为所有其他软件提供基础的运行环境。

阅读 ‧ 电子书库
图 1-1 操作系统所处的位置

操作系统和普通软件(用户态)之间的主要区别是,如果用户不喜欢某个特定的电子邮件阅读器,他可以自由选择另一个,或者选择自己写一个,但是他不能自行写一个属于操作系统一部分的时钟中断处理程序。这个程序由硬件保护,防止用户试图对其进行修改。

然而,有时在嵌入式系统(该系统没有内核态)或解释系统(如基于Java的操作系统,它采用解释方式而非硬件方式区分组件)中,上述区别是模糊的。

另外,在许多系统中,一些在用户态下运行的程序协助操作系统完成特权功能。例如,经常有一个程序供用户修改其口令之用。但是这个程序不是操作系统的一部分,也不在内核态下运行,不过它明显地带有敏感的功能,并且必须以某种方式给予保护。在某些系统中,这种想法被推向了极致,一些传统上被认为是操作系统的部分(诸如文件系统)在用户空间中运行。在这类系统中,很难划分出一条明显的界限。在内核态中运行的当然是操作系统的一部分,但是一些在内核外运行的程序也有争议地被认为是操作系统的一部分,或者至少与操作系统密切相关。

操作系统与用户(即应用)程序的差异并不在于它们所处的地位。特别地,操作系统是大型、复杂和长寿命的程序。Linux或Windows操作系统的源代码有5百万行数量级。要理解这个数量的含义,请考虑具有5百万行的一套书,每页50行,每卷1000页(比本书厚)。为了以书的大小列出一个操作系统,需要有100卷书——基本上需要一整个书架来摆放。请设想一下有个维护操作系统的工作,第一天老板带你到装有代码的书架旁,说:“去读吧。”而这仅仅是运行在内核中的部分代码。用户程序,如GUI、库以及基本应用软件(类似于Windows Explorer)等,很容易就能达到这个代码数量的10倍或20倍之多。

至于为什么操作系统的寿命较长,读者现在应该清楚了——操作系统是很难编写的。一旦编写完成,操作系统的所有者当然不愿意把它扔掉,再写一个。相反,操作系统会在长时间内进行演化。基本上可以把Windows 95/98/Me看成是一个操作系统,而Windows NT/2000/XP/Vista则是另外一个操作系统。对于用户而言,它们看上去很相像,因为微软公司努力使Windows 2000/XP与被替代的系统,如Windows 98,两者的用户界面看起来十分相似。无论如何,微软公司要舍弃Windows 98是有非常正当的原因的,我们将在第11章涉及Windows细节时具体讨论这一内容。

贯穿本书的其他主要例子(除了Windows)还有UNIX,以及它的变体和克隆版。UNIX,当然也演化了多年,如System V版、Solaris以及FreeBSD等都是来源于UNIX的原始版;不过尽管Linux非常像依照UNIX模式而仿制,并且与UNIX高度兼容,但是Linux具有全新的代码基础。本书将采用来自UNIX中的示例,并在第10章中具体讨论Linux。

本章将简要叙述操作系统的若干重要部分,内容包括其含义、历史、分类、一些基本概念及其结构。在后面的章节中,我们将具体地讨论这些重要内容。

1.1 什么是操作系统

很难给出操作系统的准确定义。操作系统是一种运行在内核态的软件——尽管这个说法并不总是符合事实。部分原因是操作系统执行两个基本上独立的任务,为应用程序员(实际上是应用程序)提供一个资源集的清晰抽象,并管理这些硬件资源,而不仅仅是一堆硬件。另外,还取决于从什么角度看待操作系统。读者多半听说过其中一个或另一个的功能。下面我们逐项进行讨论。

1.1.1 作为扩展机器的操作系统

在机器语言一级上,多数计算机的体系结构(指令集、存储组织、I/O和总线结构)是很原始的,而且编程是很困难的,尤其是对输入/输出操作而言。要更细致地考察这一点,可以考虑如何用NEC PD765控制器芯片来进行软盘I/O操作,多数基于Intel的个人计算机中使用了该控制器兼容芯片。(在本书中,术语“软盘”和“磁盘”是可互换的。)我们之所以使用软盘作为例子,是因为它虽然已经很少见,但是与现代硬盘相比则简单得多。PD765有16条命令,每一条命令向一个设备寄存器装入长度从1字节到9字节的特定数据。这些命令用于读写数据、移动磁头臂、格式化磁道,以及初始化、检测状态、复位、校准控制器及设备等。

最基本的命令是read和write。它们均需要13个参数,所有这些参数封装在9个字节中。这些参数所指定的信息有:欲读取的磁盘块地址、磁道的扇区数、物理介质的记录格式、扇区间隙以及对已删除数据地址标识的处理方法等。如果读者不懂这些“故弄玄虚”的语言,请不要担心,因为这正是关键所在——它们太玄秘了。当操作结束时,控制器芯片在7个字节中返回23个状态及出错字段。这样似乎还不够,软盘程序员还要注意保持步进电机的开关状态。如果电机关闭着,则在读写数据前要先启动它(有一段较长的启动延迟时间)。而电机又不能长时间处于开启状态,否则软盘片就会被磨坏。程序员必须在较长的启动延迟和可能对软盘造成损坏(和丢失数据)之间做出权衡。

现在不用再叙述读操作的具体过程了,很清楚,一般程序员并不想涉足软盘(或硬盘,更复杂)编程的这些具体细节。相反,程序员需要的是一种简单的、高度抽象的处理。在磁盘的情况下,典型的抽象是包含了一组已命名文件的一个磁盘。每个文件可以打开进行读写操作,然后进行读写,最后关闭文件。诸如记录是否应该使用修正的调频记录方式,以及当前电机的状态等细节,不应该出现在提供给应用程序员的抽象描述中。

抽象是管理复杂性的一个关键。好的抽象可以把一个几乎不可能管理的任务划分为两个可管理的部分。其第一部分是有关抽象的定义和实现,第二部分是随时用这些抽象解决问题。几乎每个计算机用户都理解的一个抽象是文件。文件是一种有效的信息片段,诸如数码照片、保存的电子邮件信息或Web页面等。处理数码照片、电子邮件以及Web页面等,要比处理磁盘的细节容易,这些磁盘的具体细节与前面叙述过的软盘一样。操作系统的任务是创建好的抽象,并实现和管理它所创建的抽象对象。本书中,我们将研究许多关于抽象的内容,因为这是理解操作系统的关键。

上述观点是非常重要的,所以值得用不同的表述语句来再次叙述。怀着对设计Macintosh机器的工业设计师的尊重,作者这里不得不说,硬件是丑陋的。真实的处理器、内存条、磁盘和其他装置都是非常复杂的,对于那些为使用某个硬件而不得不编写软件的人们而言,他们使用的是困难、可怕、特殊和不一致的接口。有时这是由于需要兼容旧的硬件,有时是为了节省成本,但是,有时硬件设计师们并没有意识到(或在意)他们给软件设计带来了多大的麻烦。操作系统的一个主要任务是隐藏硬件,呈现给程序(以及程序员)良好、清晰、优雅、一致的抽象。如图1-2所示,操作系统将丑陋转变为美丽。

阅读 ‧ 电子书库
图 1-2 操作系统将丑陋的硬件转变为美丽的抽象

需要指出,操作系统的实际客户是应用程序(当然是通过应用程序员)。它们直接与操作系统及其抽象打交道。相反,最终用户与用户接口所提供的抽象打交道,或者是命令行shell或者是图形接口。而用户接口的抽象可以与操作系统提供的抽象类似,但也不总是这样。为了更清晰地说明这一点,请读者考虑普通的Windows桌面以及面向行的命令提示符。两者都是运行在Windows操作系统上的程序,并使用了Windows提供的抽象,但是它们提供了非常不同的用户接口。类似地,运行Gnome或者KDE的Linux用户与直接在X Window系统(面向文本)顶部工作的Linux用户看到的是非常不同的界面,但是在这两种情形中,操作系统下面的抽象是相同的。

在本书中,我们将具体讨论提供给应用程序的抽象,不过很少涉及用户界面。尽管用户界面是一个巨大和重要的课题,但是它们毕竟只和操作系统的外围相关。