MIT 6.828 book_xv6:Appendix A

xv6:附录 A


MIT 6.828 Operating System Engineering

PC硬件

本目录介绍xv6的运行平台,PC硬件。

PC是一种符合多个行业标准的计算机,其目标是给定的软件可以在多个供应商销售的PC上运行。这些标准随着时间的推移而演变,从上世纪九十年代开始的PC现在看起来并不像个人电脑

从外部看,PC是一个带有键盘、屏幕和各种设备(CD-rom等)的盒子。盒子里有一个电路板(主板),带有CPU、内存、显卡、I/O控制芯片和总线,芯片通过这些电路板进行通信。总线遵循标准协议(如PCI和USB),以便设备与各个供应商的PC一起协作

从我们的角度看,我们可以将PC抽象为三个组件:CPU、内存和I/O设备。CPU执行计算,内存包含该计算所需的指令和数据,设备允许CPU与硬件相互交互以进行存储、通信和其他功能

您可以将主存视为连接到CPU的一组电线或线路,一些用于地址位,一些用于数据位,一些用于控制标志。要从主存中读取值,CPU在规定的时间内发送高或低电压,在地址线上表示1或 0位,在“读取”行上发送1,然后通过解释数据线上的电压来读回该值。要将值写入主内存,CPU将在地址和数据行上发送适当的位,并在规定的时间内在“写入”行上发送1。真正的内存接口比这更复杂,但只有在需要实现高性能的情况下,这些细节才很重要

处理器与内存

计算机的CPU(中央处理单元或处理器)运行一个概念上的简单循环:它从一个叫做程序计数器的寄存器中查询一个地址,从内存中的该地址读取计算机指令,通过该指令改变程序计数器,并执行指令,然后重复该循环。如果指令的执行没有改变程序计数器,此循环将把程序计数器指向的内存解释为一个接一个运行的机器指令序列。更改程序计数器的指令包括分支和函数调用???

如果没有存储和修改程序数据的能力,执行引擎是没有用的。处理器的寄存器集提供了最快的数据存储。寄存器是处理器内部的存储单元。能够容纳计算机以字为单位的值(通常为16、32或64位)。存储在寄存器中的数据通常可以在单个CPU周期中快速读取或写入

PC都有一个实现了x86指令集的处理器,这最早由Intel定义,现在已经成为了一个标准。一些制造商就根据该标准去生产相应的处理器。就像其他PC标准,该标准也在不断发展,而且新的标准会兼容旧的标准。引导装载程序(The boot loader)不得不去处理其中的变化,因为每个PC处理器在开机时均模拟成因特尔的8088,这个CPU芯片最早是IBM在1981年发布的。然而,在xv6中,大部分情况是你仅需要关心现代x86指令集

现代x86指令集提供8个通用32位寄存器%eax %ebx %ecx %edx %edi %esi %ebp %esp和一个程序计数器%eip(指令指针)。前缀e表示extended(扩展),因为它们是16位寄存器%ax %bx %cx %dx %di %si %bp %sp %ip的32位扩展。这两个寄存器集互为别名(are aliased),因此,像%ax%eax的下半部分,写入% ax会更改存储在%eax中的值,反之亦然。前四个寄存器的低字节部分的两个8位字节还有别名:%al %ah分别代表%ax的高和低8位;%bl %b %cl %ch %dl%dh也是同样模式。除了这些寄存器,x86还有8个80位浮点寄存器和少量特殊用途的寄存器,如控制寄存器%cr0 %cr2 %cr3 %cr4;调试寄存器:%dr0 %dr1 %dr2 %dr3;段寄存器:%cs %ds %es %fs %gs %ss;全局和本地描述符表伪寄存器%gdtr%ldtr。控制寄存器和段寄存器对任何操作系统都非常重要。浮点寄存器和调试寄存器在xv6中,则没有得到关心和使用

寄存器速度快但是价格昂贵。大多数处理器最多提供几十个通用寄存器。存储的下一个层次就是随机存取内存(RAM)。主存一般比寄存器慢10-100倍,但要便宜得多,因此内存会更大。内存相对较慢的一个原因是它在物理上和处理器芯片分离。x86处理器有几十个寄存器,但如今典型的PC却有千兆字节的内存。由于寄存器和主内存之间在访问速度和大小方面的巨大差异, 大多数处理器 (包括x86)都会将最近访问的主内存部分的副本存储在高速缓存内存中(Cache)。高速缓存在访问时间和大小上都充当寄存器和内存之间的中间地带。如今的x86处理器通常都有二级缓存,较小的一级缓存,其访问速度相对接近处理器的时钟频率,较大的第二级缓存的访问时间在第一级缓存和主存之间。下表显示了Intel Core 2 Duo芯片的真实数据:

大多数情况下,x86处理器对操作系统隐藏了缓存(Cache),因此我们可以将处理器视为只有两种存储类型:寄存器和主存,不用关心不同内存层级的不同级别之间的区别

I/O

处理器需要与设备和内存通信。x86处理器提供特殊的读取写入指令,用于从称为I/O 端口的设备地址读取值。这些指令的硬件实现与读取和写入内存基本相同。早期x86处理器有一个额外的地址行:0表示从I/O端口读写,1表示从主内存读写。每个硬件设备监视这些地址行,以获取分配的读写I/O端口的范围。设备的端口允许软件配置设备,检查状态,并导致设备执行操作。例如,软件使用I/O端口去读写来控制磁盘接口硬件去读写磁盘扇区

很多计算机体系结构没有单独的设备访问指令。相反,这些设备有固定的内存地址,处理器通过读写这些地址的值和设备通信(在操作系统的命令下)。事实上,现代x86结构在大多数高速设备(如网络、磁盘和图形控制器)中使用了这种称为内存映射 I/O(memory-mapped I/O)的技术。不过,处于向后兼容的原因,旧的inout指令保留下来,对legacy硬件设备使用它们,比如xv6中使用的IDE磁盘控制器