操作系统必须与其作为基础的硬件系统紧密合作。操作系统需要某些只能由硬件提供的服务。为了充分理解 Linux 操作系统,您需要了解底层硬件的基础知识。本章简要介绍现代 PC 硬件。
当 1975 年 1 月的《大众电子》杂志封面印有 Altair 8080 的插图时,一场革命开始了。Altair 8080 以早期《星际迷航》剧集的目的地命名,家庭电子爱好者只需 397 美元即可组装。它配备了英特尔 8080 处理器和 256 字节的内存,但没有屏幕或键盘,以今天的标准来看是很弱小的。它的发明者埃德·罗伯茨创造了“个人计算机”一词来描述他的新发明,但术语 PC 现在用于指代几乎任何无需帮助即可搬动的计算机。按照这个定义,即使是一些非常强大的 Alpha AXP 系统也是 PC。
充满热情的黑客看到了 Altair 的潜力,并开始为其编写软件和构建硬件。对于这些早期的先驱者来说,它代表着自由;摆脱由精英祭司阶层运行和守护的大型批处理主机系统的自由。一夜之间,那些被这种新现象迷住的大学辍学生发了财,这是一种你可以放在家里厨房桌子上的电脑。出现了许多不同的硬件,软件黑客们很高兴为这些新机器编写软件。具有讽刺意味的是,正是 IBM 通过在 1981 年发布 IBM PC 并在 1982 年初交付给客户,牢固地塑造了现代 PC 的模具。它配备了英特尔 8088 处理器、64K 内存(可扩展到 256K)、两个软盘驱动器和一个 80 字符 x 25 行彩色图形适配器 (CGA),以今天的标准来看并不强大,但销量很好。1983 年,IBM PC-XT 紧随其后,它奢侈地配备了 10Mbyte 硬盘驱动器。不久之后,康柏等许多公司开始生产 IBM PC 克隆机,PC 的架构成为事实上的标准。这个事实上的标准帮助众多硬件公司在不断增长的市场中相互竞争,这对消费者来说是幸运的,因为它保持了低价。这些早期 PC 的许多系统架构特性已被沿用到现代 PC 中。例如,即使是最强大的基于英特尔奔腾 Pro 的系统也以英特尔 8086 的寻址模式启动运行。当 Linus Torvalds 开始编写后来成为 Linux 的操作系统时,他选择了最丰富且价格合理的硬件,即英特尔 80386 PC。
从外部观察 PC,最明显的组件是系统机箱、键盘、鼠标和视频显示器。系统机箱的正面有一些按钮、一个显示一些数字的小显示屏和一个软盘驱动器。现在大多数系统都有 CD-ROM,如果您觉得需要保护您的数据,那么还会有磁带驱动器用于备份。这些设备统称为外围设备。
虽然 CPU 总体上控制着系统,但它并不是唯一的智能设备。所有外围控制器,例如 IDE 控制器,都具有一定程度的智能。在 PC 内部(图 1.1),您将看到一个主板,其中包含 CPU 或微处理器、内存以及用于 ISA 或 PCI 外围控制器的多个插槽。一些控制器,例如 IDE 磁盘控制器,可以直接构建到系统主板上。
CPU,或者更确切地说是微处理器,是任何计算机系统的核心。微处理器通过从内存中读取指令然后执行它们来进行计算、执行逻辑运算和管理数据流。在计算的早期,微处理器的功能组件是分离的(并且物理尺寸很大)单元。这就是“中央处理器”一词的由来。现代微处理器将这些组件组合到蚀刻在非常小的硅片上的集成电路中。术语 CPU、微处理器 和 处理器 在本书中可以互换使用。
微处理器处理二进制数据;即由 1 和 0 组成的数据。
这些 1 和 0 对应于电气开关的开或关状态。正如 42 是一个十进制数,表示“4 个 10 和 2 个单位”一样,二进制数是一系列二进制数字,每个数字代表 2 的幂。在这种上下文中,幂表示一个数字与其自身相乘的次数。10 的 1 次方 (101) 是 10,10 的 2 次方 (102) 是 10x10,103 是 10x10x10,依此类推。二进制 0001 是十进制 1,二进制 0010 是十进制 2,二进制 0011 是 3,二进制 0100 是 4,依此类推。因此,十进制 42 是二进制 101010 或(2 + 8 + 32 或 21 + 23 + 25)。与其在计算机程序中使用二进制来表示数字,不如通常使用另一种进制,即十六进制。
在这种进制中,每个数字代表 16 的幂。由于十进制数字仅从 0 到 9,因此数字 10 到 15 用字母 A、B、C、D、E 和 F 表示为单个数字。例如,十六进制 E 是十进制 14,十六进制 2A 是十进制 42(两个 16)+ 10)。使用 C 编程语言表示法(正如我在本书中始终使用的那样),十六进制数字以 “0x” 开头;十六进制 2A 写为 0x2A。
微处理器可以执行算术运算,例如加法、乘法和除法,以及逻辑运算,例如“X 是否大于 Y?”。
处理器的执行由外部时钟控制。这个时钟,即系统时钟,向处理器生成规则的时钟脉冲,并且在每个时钟脉冲时,处理器都会执行一些工作。例如,处理器可以每时钟脉冲执行一条指令。处理器的速度以系统时钟滴答率来描述。一个 100Mhz 的处理器每秒将接收 1 亿个时钟滴答。用其时钟频率来描述 CPU 的能力是具有误导性的,因为不同的处理器每个时钟滴答执行的工作量不同。然而,在所有条件相同的情况下,更快的时钟速度意味着更强大的处理器。处理器执行的指令非常简单;例如“将内存位置 X 的内容读取到寄存器 Y 中”。寄存器是微处理器的内部存储,用于存储数据并在其上执行操作。执行的操作可能会导致处理器停止正在执行的操作并跳转到内存中其他位置的另一条指令。这些微小的构建块赋予现代微处理器几乎无限的能力,因为它每秒可以执行数百万甚至数十亿条指令。
指令必须在执行时从内存中获取。指令本身可能会引用内存中的数据,并且该数据必须从内存中获取并在适当的时候保存到那里。
微处理器中寄存器的大小、数量和类型完全取决于其类型。英特尔 4086 处理器与 Alpha AXP 处理器具有不同的寄存器集;首先,英特尔的寄存器是 32 位宽,而 Alpha AXP 的寄存器是 64 位宽。但总的来说,任何给定的处理器都将具有多个通用寄存器和少量专用寄存器。大多数处理器都具有以下专用寄存器
一些处理器的堆栈向上增长到内存顶部,而另一些处理器的堆栈向下增长到内存底部或基址。一些处理器支持这两种类型,例如 ARM。
高速缓存和主内存必须保持同步(一致)。换句话说,如果主内存的一个字保存在高速缓存中的一个或多个位置,那么系统必须确保高速缓存和内存的内容相同。高速缓存一致性的工作部分由硬件完成,部分由操作系统完成。对于许多主要的系统任务也是如此,在这些任务中,硬件和软件必须紧密合作才能实现其目标。
所有控制器都不同,但它们通常都具有控制它们的寄存器。在 CPU 上运行的软件必须能够读取和写入这些控制寄存器。一个寄存器可能包含描述错误的状态。另一个寄存器可能用于控制目的;更改控制器的模式。总线上的每个控制器都可以由 CPU 单独寻址,这是为了使软件设备驱动程序可以写入其寄存器,从而控制它。IDE 排线就是一个很好的例子,因为它使您能够分别访问总线上的每个驱动器。另一个很好的例子是 PCI 总线,它允许独立访问每个设备(例如图形卡)。
有时,控制器需要直接从系统内存读取或写入大量数据。例如,当用户数据正在写入硬盘时。在这种情况下,使用直接内存访问 (DMA) 控制器允许硬件外围设备直接访问系统内存,但此访问受到 CPU 的严格控制和监督。