我打算写一些计算机内在结构的博文来解释现代操作系统是怎么工作的。

我们先来看一下一台Intel电脑是怎么组合的。下图展示了主板上的主要部件和(原作者)对于颜色可疑的品味。

bios 启动 内存映射 主板bios内存映射_操作系统

当你看到这里的时候,你需要记住的一件很重要的事情是CPU实际上不知道它连接的是什么东西。它通过针脚和外界通信,但它不在意外界是什么。外界可能是主板,也可能是烤面包机,路由器,或者是CPU测试工作台。CPU主要通过三种方式和外界通信:内存地址空间,IO地址空间,和中断。我们现在只需要关心主板和内存。

在主板中,CPU连向世界的网关是和北桥相连接的前端总线,每当CPU需要读写内存时,它通过这根总线实现。它使用一些针脚传输它想要读写的物理内存的地址,使用另一些针脚传输读取或写入的值。Intel Core 2 QX6600有33个针脚来传输物理内存地址(所以有2^33种内存地址选择)和64个针脚发送接受数据(所以数据在64-bit数据通路中传输)。这允许CPU访问64 gigabytes大小的内存,虽然大多数芯片级只能处理8 gigabytes的RAM.

现在问题来了。我们已经习惯了认为内存就是RAM,程序总是读写RAM。实际上绝大多数来自处理器的内存请求是被北桥芯片转发给RAM,但不是全部。物理内存地址也被用来和主板上各种各样的设备通信(这种通信也被称作内存映射IO)。这些设备包括显卡,大多数PCI卡,还有存储BIOS的闪存。

当北桥接收到物理内存请求时,它决定了转发到哪:转发到RAM?或者显卡?这个转发通过内存地址映射决定。对于每个区域的物理内存地址,内存映射知道哪个设备拥有那个区域。大多数地址被映射到RAM,但不被映射到RAM的时候,内存映射告诉芯片集应该向哪个设备请求服务。这种映射方式导致了经典的PC 640KB和1M之间的内存缝隙。如果有为显卡和PCI设备保存的内存地址,会出现更大的缝隙。这是为什么32位的操作系统会存在使用4G RAM的问题。在Linux文件/proc/iomem中清楚地列出了这些地址范围映射。下图显示了Intel PC上的4GB地址映射。

bios 启动 内存映射 主板bios内存映射_内存_02

具体的地址和范围取决于具体的主板和设备,但是大多Core 2系统和上述很接近。所有棕色的区域都不映射到RAM。记住主板上使用的这些都是物理地址。在CPU内部(比如,我们运行的程序),内存地址是逻辑地址,并且在通过总线访问内存之前,它们必须被CPU翻译成物理地址。

把逻辑地址翻译成物理地址的规则是复杂的并且它们依赖CPU运行的模式(实时模式,32位保护模式,和64位保护模式)。无论地址变换机制如何,CPU模式决定了物理内存能否被访问。举个例子,如果CPU运行在32位模式下,那么只能访问4G物理地址。因为顶部大约1G的物理地址被映射到主板设备上,CPU只能利用RAM的3GB。如果CPU运行在实时模式,那么只能使用1MB物理地址。另一方面,运行在64位模式的CPU可以访问64GB地址。在64位模式下,CPU访问超过RAM内存大小的地址,使用被主板设备偷走的内存(顶部1GB)是可能的。这被叫做回收内存并且它在芯片集的帮助下完成。