主板芯片组和内存映射

最近一直想了解在学习内存方面的编程,但是一直不理解这个内存是什么东西,然后就一直搜索,找到一个大神的一些深刻解释。

版权归原作者所有,仅供学习。

文章:https://manybutfinite.com/archives/(原文地址:http://duartes.org/gustavo/blog/)

原文标题:Motherboard Chipsets and the Memory Map

这第一篇文章讲述现代Intel主板的布局,CPU如何访问内存,以及系统的内存映射。

       首先我们跳过Intel x86_64 CPU的具体实现,把它看成一个模型。这个简化的CPU模型包括以下部分:寄存器,Cache,MMU以及针脚。这里着重说一下针脚(pin),因为它是CPU与外界沟通的唯一方式。

主板芯片组和内存映射_第1张图片

                                                                                            Intel 80486DX2 CPU针脚

       CPU的针脚连接到主板的前端总线(Front-end Bus)上,进而与北桥芯片组相连。不同的针脚用途不同:有传送物理内存地址的,有传送数据和指令的,也有用来传送中断信号的。例如Intel Core 2 QX6600 CPU有A[35:3]这33根针脚来传送8位对齐的物理内存地址,D[63:0]这64根针脚传送要读或者写的64位的数据。那么该CPU理论上所支持的最大物理内存是2^33 * 64 = 2^39 bit =64GB。

CPU运行有三个模式,实模式,32位保护模式以及64位保护模式。实模式下CPU支持最大1MB内存寻址,32位CPU支持最大4GB内存寻址。

       另外,CPU在保护模式下执行程序的时候访问的内存地址实际上是逻辑地址(logical address),必须由MMU进行翻译成物理地址之后才能发往总线。

让我们看看当今的Intel计算机是如何连接各个组件的吧。下图展示了主板上的主要组件:

主板芯片组和内存映射_第2张图片

                                                                                    主板示意图,北桥和南桥构成了芯片组

       当你在理解上图时,需要重点注意的一点是CPU并不知道它和什么东西连接在一起,它通过引脚(pins)和外部交流,但并不关心外部环境是什么:可能是主板,但也可能是烤面包机、路由器、植入大脑或者是CPU测试器。CPU主要通过三种方式与外部环境通信:存储地址空间、I/O地址空间和中断。现在我们只关注主板和存储。

       在一块主板中,CPU与外部通信的通道为连接在北桥(northbridge)上的前端总线(front-side bus),无论何时CPU需要读写数据,都需要通过前端总线。CPU使用一些引脚来传输它要读写的物理存储地址,还有一些引脚传送要写入的数据或是接受读取到的数据。一个Intel Core 2 QX6600有33个用来传送物理地址的引脚(所有有233个可以表示的地址)和64个用来传送和接受数据的引脚(所以被传输的数据为64位即8个字节),因此CPU可以使用64GB的物理地址空间(233个地址 * 8字节)虽然大多数的芯片组只支持最大8GB的内存。

       这里有一个可能会和你的认识冲突的事实:我们总是认为存储空间只是指内存(RAM),就是程序一直在读写的那个东西,实际上大部分处理器的读写请求也确实是被北桥转发给了内存模块,但并不是所有的。物理存储地址空间同时也被用来和一些主板上的其他设备通信(这种通信被称为memory-mapped I/O),比如显卡和大部分的PCI设备(扫描仪、SCSI设备之类的),还有存储有BIOS的闪存。

       当北桥接收到一个物理地址请求,北桥会决定这个请求该转向哪里:内存?还是显卡?北桥根据存储地址映射表来决定。对物理存储地址的每一个区域,存储地址映射表都知道究竟是哪一个设备拥有这些地址。大部分的地址都映射到内存中,但当地址不属于内存时,存储地址映射表会告诉芯片组哪个设备该响应这些地址的请求。这种将地址分配到其他设备的映射导致了在老式PC存储中640KB到1MB之间的空洞,而保留给显卡和PCI设备的地址又造城了一个更大的空洞,这也是为什么32位操作系统不能完全使用4GB内存的原因。在Linux中/proc/iomem文件清楚的列出了这些被映射的地址。下图展示了Intel PC的前4GB地址空间中典型的映射关系:

主板芯片组和内存映射_第3张图片

                                                                                        Intel体系中前4GB存储空间的布局情况

       实际的地址和范围取决于电脑中使用的主板和设备,不过大部分的Core 2系统和上图中展示的非常相似。所有棕色的区域都不属于内存,这里要明确一点,这里所说的地址是在主板总线中实际的物理地址,在CPU内部(例如程序中的运行、读写地址)使用的地址都是逻辑地址,并且在实际访问之前都必须被CPU转换成物理地址。

       将逻辑地址转换成物理地址的规则十分复杂,并且依赖于CPU运行时处于的模式(实模式、32位保护模式以及64位保护模式)。抛开地址转换硬件不谈,CPU的运行模式决定了究竟能够访问多少物理地址。举例来说,如果CPU运行在32位保护模式中,则它最多只能够使用4GB的物理地址(有一个例外叫做physical address extension,不过在这里我们先忽略它),因为最顶部的1GB地址空间被映射给了主板上的设备,CPU只能有效利用不到3GB的内存(有时候会更少-我有一台Vista机器只能使用2.4GB内存);如果CPU运行在实模式(real mode)中,则它只能使用1MB的物理地址(实模式是早期Intel CPU唯一能够使用的模式);而如果CPU运行在64位保护模式中,它可以使用64GB的物理地址(虽然仅仅只有少数芯片组支持这么多的内存),在64位模式中使用超过内存总容量的物理地址空间是可能的,系统通过对那些被主板设备偷走的存储地址对应的内存区域的访问来实现这点,这叫做内存回收(reclaiming memory),是在主板芯片组的支持下完成的。

       以上就是在下一篇文章前我们需要的所有关于存储的知识了。下一篇文章将会讲解从计算机通电到boot loader即将跳转到内核之间的过程。如果你还想了解更多关于存储的知识,强烈推荐阅读Intel手册,Intel的手册写的很好,而且非常准确,下面给出一些:

  • Datasheet for Intel G35 Chipset中给出了Core 2系列处理器具有代表性的芯片组的文档,是本文的主要参考。
  • Datasheet for Intel Core 2 Quad-Core Q6000 Sequence是处理器的文档,详细的讲解了处理器的每一个引脚(实际上并没有那么多,并且在对它们分组之后更加没有多少了),虽然有些难懂,但还是非常赞。
  • 广为人知的Intel Software Developer’s Manuals,易于理解,非常优美的解释了很多体系结构上的问题。卷1和卷3A里有很多有用的东西(别被名字吓到了,“卷”其实并不长而且你也可以选择性的进行阅读)

参考链接:

https://manybutfinite.com/archives/

http://blog.kongfy.com/2014/03/%E8%AF%91%E4%B8%BB%E6%9D%BF%E8%8A%AF%E7%89%87%E9%9B%86%E5%92%8C%E5%AD%98%E5%82%A8%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84-motherboard-chipsets-and-the-memory-map/

https://www.jianshu.com/p/eecbbc93c56d

你可能感兴趣的:(内存篇)