原文标题:Motherboard Chipsets and the Memory Map
原文链接:https://manybutfinite.com/post/motherboard-chipsets-memory-map/
原文发布时间:Jun 4th, 2008
我正要写一些关于计算机内部的帖子,目标是解释现代内核是如何工作的。我希望它们对于那些对感兴趣但是没有经验的爱好者和程序员有用。我们专注于 Linux、Windows 和 Intel 处理器。计算机内部是我的一个小爱好,我已经写了相当量的内核态代码,但是这段时间没有写了。第一个帖子描述了基于 Intel CPU 的现代主板,以及 CPU 是如何访问内存和系统内存映射。
开始之前我们先看一下一个 Intel 计算机是如何连接在一起。下图展示了主板里的主要组件:
现代主板的图。北桥和南桥组成了芯片组。
当你看到这个,最重要的事情是记住,CPU 不会真正知道它连接了什么。它通过pins和外部世界进行联系。它可能是一台计算机的主板,但也可能是一个烤面包机、网络路由器、大脑植入物或 CPU 测试台。CPU 和外部通信的主要方式有三种:内存地址空间、I/O 地址空间和中断。我们现在只关注主板和内存。
在主板上,CPU 通向世界的网关是连接它和北桥的前端总线。CPU 通过这个总线来读写内存。它使用一些引脚来传输它想要写入或读取的物理内存地址,而其他引脚发送要写入的值或接收要读取的值。一个 Intel Core 2 QX6600 有 33 个引脚来传输物理内存地址(因此有 2^33 个内存地址)和 64 个引脚来发送或接收数据(因此数据在一个 64 位的数据路径上传输,也就是 8 字节的数据块)。这允许 CPU 物理寻址 64GB 的内存(2^33 个地址 * 8 字节),尽管大多数芯片组只能处理 8GB 的 RAM。
现在问题来了。我们习惯于只从 RAM 的角度来考虑内存,也就是程序一直都在读写的东西。事实上,大多数来自处理器的内存请求都是通过北桥路由到 RAM 模块的。但不是所有的。物理内存地址也用于与主板上的各种设备进行通信(这种通信称为内存映射 I/O)。这些设备包括显卡、大多数 PCI 卡(例如扫描仪或 SCSI 卡),以及存储 BIOS 的闪存。
当北桥收到一个物理内存请求,它来决定把请求路由到哪里:应该路由到 RAM?显卡?这个路由由内存地址映射来决定的。对于物理内存地址的每个区域,内存映射知道拥有该区域的设备。大部分的地址被映射到 RAM,但是当它们不是映射到 RAM 时,内存映射会告诉芯片组哪个设备应该为这些请求地址服务。这些不是没有映射地址到 RAM 模块的导致内存在 640KB 到 1MB 之间出现经典的空洞。当内存地址为显卡和 PCI 设备预留内存地址时,这个空洞就更大了。这就是为什么 32 位的操作系统使用 4GB 的 RAM 会有问题。Linux 文件/proc/iomem
整齐地列出了这些地址范围的映射。下图展示了一个典型的内存映射(为 Intel PC 的最开始的 4GB 的物理内存进行内存映射):
Intel 系统中最开始的 4GB 内存的布局。(译者注:这是物理内存的映射,不要和虚拟内存映射搞混了,例如最终转化出来的物理地址为 0xFFFFE,那就是在访问 System BIOS。)
实际的地址和范围取决于计算机中特定主板和设备,但大多数 Core 2 系统非常接近上述。所有的棕色区域都是 RAM 之外的映射。记住,这些是在主板总线上使用的物理地址。在 CPU 内部(例如,在我们运行和编写的程序中),内存地址是逻辑的,在总线上访问内存之前,它们必须被 CPU 转换成物理地址。
逻辑地址转化为物理地址的规则很复杂,它取决于 CPU 运行的模式(实模式、32 位保护模式和 64 位保护模式)。不管转换机制如何,CPU 模式决定可以访问多少物理内存。例如,如果 CPU 在 32 位模式下运行,那么它只能物理寻址 4GB(好吧,有一个例外称为物理地址扩展的,但现在忽略它)。由于前面 1GB 左右的物理地址被映射到主板设备,CPU 只能有效地使用 3GB 的 RAM(有时甚至更小 - 我有一个 Vista 机器只能用 2.4GB 的 RAM。)如果 CPU 处于实模式,那么它只能处理 1MB 的物理 RAM(这是早期 Intel 处理器的唯一模式)。另一方面,在 64 位模式下运行的 CPU 可以访问 64GB 的 RAM(少数芯片组可以支持那么多 RAM)。在 64 位模式下,可以使用系统中总 RAM 以上的物理地址来访问 RAM 区域,对应了主板设备上“偷去”的物理地址。这些被称为 reclaiming memory,它是在芯片组的帮助下完成的。
这就是我们下一篇文章所需要的全部内存,它描述了从电源启动到引导加载程序即将进入内核的引导过程。如果你想了解更多关于这方面的知识,我强烈推荐 Intel 手册。总的来说,我很喜欢第一手资料,但 Intel 的手册写得很好,也很准确。这里有一些:
- Datasheet for Intel G35 Chipset documents a representative chipset for Core 2 processors. 这是这篇的文章的主要来源。
- Datasheet for Intel Core 2 Quad-Core Q6000 Sequence is a processor datasheet. 它给出了处理器中的每个引脚(实际上并没有那么多,并且在你将它们分组之后,它真的没有很多内容)的文档。有趣的东西,尽管有些地方很神秘。
- Intel Software Developer’s Manuals 非常出色。这些手册一点也不神秘,它们漂亮地解释了所有关于架构的事情。第 1 卷和第 3 卷有很多好东西(不要被名字所迷惑,“卷”很小,你可以有选择地阅读)。
- Pádraig Brady 建议我放上 Ulrich Drepper 的出色的关于内存的论文。这是好东西,我想把它放到一篇关于内存的帖子里,但是这里些也可以放,毕竟越多越好。