其它体系结构我没有深入研究过,然而对于x86而言,我们很多人都是很了解的。其内存可以支持4G(不考虑PAE),因为地址总线为32位,也就是说32条1位的线缆可以选择4G的地址,因此我们想当然的认为我们买了两条2G的内存插入以后,我们的系统就可以有4G的内存可用了,我们的系统内存在满载运行,然而果真如此吗?答案是否定的!
因为所谓的地址总线32位是指从cpu引脚出来的总线是32位,是针对于cpu而言的,具体这些总线最终能全部连接在主板的ram上吗?会不会还会连接到其它的设备上呢?这要看主板怎么设计了。这里主板上的北桥芯片解除了cpu和设备之间的地址偶合,典型的设计为cpu出来的地址总线32位全部连接在北桥芯片之上,当cpu发出一个32位的地址比如0xcb000000的时候,由北桥来决定该地址发往何处,可能发往内存ram,也可能发往显示卡,也可能发往其它的二级总线,当然也可能发往南桥芯片(一个类似的解析地址的芯片,北桥解耦了cpu和主板芯片/总线,而南桥则解耦了主板芯片/总线和外部设备,比如ata硬盘,usb之类的设备就可以连接在南桥芯片上)。如果北桥选择将该地址发往PCI总线上,那么显然内存ram就收不到这个地址请求,而且自从主板设计好了之后,理论上该地址就永远被发送给了PCI,当然了,你可以通过诸如跳线之类的办法来更改之,(而且现在很多板子都有被bios“自动探测/识别/设置”的功能,此种情形下地址拓扑信息就不必记录在bios里面了,而是在bios开始运行的时候自动生成,生成的方式不外乎侦测-往特定针脚发送电平序列信号,然后得到回复,不过具体往哪里发送电平信息也必须由主板和cpu来确定标准),因此虽然你有4G的所谓的满载的ram,然而它的地址0xcb000000却不能被使用。以上仅仅是一个例子,主板上还有很多的设备或者总线会占据一些地址总线上的地址,这样说来你的4G的ram会有很多不能使用,典型的,intel提出了PAE,即物理地址扩展,使得可以支持4G以上的ram,实际上它的实现很简单,就是为ram增加几个地址总线位,变成36位的地址总线,这样就可以插入64G的ram了,这时4G以上的地址总线空间将不会被其它设备占据,而北桥只会将地址发往ram。
既然4G的地址空间不能完全由ram内存条使用,那么ram不能使用哪些地址呢?这个信息很重要,因为这个信息会指导操作系统内核进行物理内存分配,比如其它地址使用的地址处的页面就不能被分配,否则就访问到设备了,因此这些个地址处的页面应该设置为保留,永远不能被使用,事实上,它们被浪费了。这些地址信息存放的位置是BIOS,BIOS里面存放着很重要的信息,这些信息可以组成一张逻辑拓扑图,真实反映主板上的芯片是如何排列放置的,待到主板上电后,主板上的芯片和总线就形成了一张真实的“地图”,在bios拓扑图的指导下被检测。
既然BIOS里面存放拓扑图,那么操作系统内核在启动的时候怎样得到它呢,得到了它之后,操作系统才能建立自己的物理地址空间映射。得到bios信息的办法莫多于bios调用了,也就是0x15调用,参数由寄存器指定,如果你想得到地址信息,也就是那张拓扑图,那么你要将eax设置成0X0000E820,然后读取返回即可,以下是Linux在拥有256M内存的机器上得到的地址信息,该信息在内核启动的时候通过bios调用得到: