地址空间映射

首先简单介绍一下DRAM和CPU寻址,DRAM相对于CPU也可以算是外部设备,CPU地址空间是CPU访问外部设备过程中的一个概念,CPU除了访问DRAM外还会访问许多其他的设备。可以粗略的认为CPU地址空间包含DRAM地址空间,但两者却是不同的概念。而且DRAM地址空间是由内存控制器直接访问的,由CPU间接访问的。

过去很长一段时间Intel CPU是32位的,也就是可以访问到4GB的地址空间,但是当时的DRAM通常也就是512MB到2GB之间,现在假设DRAM是1GB,那么就是3GB的地址空间是空的。在计算机里面,地址也是资源。这空的地址空间就用来访问外部设备所用,这部分被称为MMIO(Memory Mapped I/O)。MMIO的空间是很大的,它包含了PCI的配置空间(256MB或者更大),内置集成显存(256MB,或者更大),还有其他很多东西 。所以这部分的大小是不容忽视的。

这里先粗略的将未使用的地址空间全归类到MMIO中,后续会有详细介绍,本节对CPU地址空间和内存有个整体的认识

现在的Intel CPU一般都是36位的,也就是可以访问到64GB。而DRAM也是越来越大,以至于DRAM加上MMIO的空间超出了4GB,而MMIO的空间是不能随意变更的。所以现在的做法就是将DRAM的一部分重映射到4GB以上的空间,下面就以DRAM有5GB为情况,做一个例子。请看下图

TOLUD:较低可用DRAM的顶部,在一些其他地方也可能用TOLM(Top of Low Memory)表示,他们的含义就是在4GB之下,区分MMIO和DRAM的分界线,由上图可知DRAM被MMIO占用的地址空间,被重映射到了4GB之上的地方。

TOLUD的值由BIOS指定

x86的CPU空间和PCI空间

cpu地址空间和pci地址空间是两个常用的比较容易混淆的概念,特别是其中不同系列的cpu的实现还各不相同:x86系列cpu地址空间和pci地址空间是重合的,即为同一空间。
上文提到了TOLM-4G的空间作为MMIO,用于访问外部设备

x86系列的IO空间和CFG空间

由于x86 cpu对pci标准的完美支持,所以x86 cpu还支持pci的io空间访问和pci的配置空间访问:

  • io空间:pci标准规定的io地址空间最大可以有4G,但是x86只实现了64k的大小。io空间用来实现早期兼容的外设寄存器的访问(IO端口),和用来映射pci外设的io空间。
  • 配置空间:用来访问pci总线设备的配置空间,访问配置空间的方法有两种:
    • 是通过CF8/CFC io端口的间接访问来访问配置空间;
    • 是通过mmcfg方式,把配置空间映射到memory空间来访问。对每个配置空间来说,CF8/CFC方式只能访问传统的pci配置空间256字节,而mmcfg访问方式,能访问pcie的整个配置空间4k。

地址空间布局

本节介绍详细的地址空间布局,说明各个地址范围的作用,如下图所示

地址范围 名称 说明 备注
0-9FFFFF 0-640k常规内存(MS-DOS Area) 这一段区域就是ram。 其中有功能划分的区域是:起始位置的1 KB被用做BIOS中断向量表,随后的1 KB被用做BIOS数据区
A0000-BFFFF 640 – 768 kB Video Buffer Area 这一段区域是显卡的显示RAM区域,老式的VGA显示模式直接往这段显存写数据,就可以显示。现在估计只有bios阶段使用这种显示方式,系统起来后会开启更高级的显卡显示模式。 PCI在支持VGA显示时,有个VGAEN功能,比较特殊,值得关注。VGA显卡设备不需要配置常规的pci bar寄存器地址,而只需要使能显卡所挂在PCI-PCI桥设备的配置寄存器0x3E bit 3(VGA Enable),显卡就会响应专为VGA保留的固定pci memory地址(A0000-BFFFF)和pci io地址(03c0-03df)。
C0000-CFFFF 768 - 832 kB VGA Video BIOS ROM IDE Hard Disk BIOS ROM Optional Adapter ROM BIOS or RAM UMBs 这一段区域存放显卡的Option Rom还有其他设备的OptionRom(如硬盘、网卡..)。 这一段区域,是OptionRom和BIOS区域覆盖了原RAM区域。由于RAM的访问速度远远快于这些固件的访问速度,所以通常的做法是把固件中的内容拷贝到相同地址的RAM中,然后再使能RAM而屏蔽原有的固件映射。 访问BIOS和OptionRom内容和地址都没有改变,但是速度却加快了。这种做法就叫ROM Shadowing
D0000-DFFFF 832 - 896 kB Optional Adapter ROM BIOS or RAM UMBs 这一段区域也是来存放设备的OptionRom。如果没有OptionRom覆盖,那就是常规内存
E0000-EFFFF 896 - 960 kB System BIOS Plug and Play Extended Information 扩展BIOS区域。
F0000-FFFFF 960 kB–1 MB System BIOS ROM 常规BIOS区域,映射到BIOS芯片。CPU的第一句指令0xFFFF0就跳到该区域
1M-TOLM 低于4G的常规内存 这一段的内存就是低于4G的可用的内存,其中有两段区域比较特殊。 1、15 MB - 16 MB Window (ISA Hole)传统的ISA黑洞,现在基本不支持。 2、Extended SMRAM Space (TSEG)扩展SMM内存。前面已经有VGA RAM覆盖的128k内存可做SMM内存使用,系统还允许分配更多的SMM内存。
HECBASE-(HECBASE+256M) MMCFG:映射到memory空间的pci配置寄存器 256M的计算方法: 256bus x 32device x 8function x 4k bytes = 256M bytes mmcfg、mmio这两段区域覆盖的相同地址的常规内存比较大,怎么样能使用到这段被覆盖的内存? 芯片组和内存控制其有一种叫做Main Memory Reclaim AddressRange。通过这个技术可将重叠得部分的内存地址印射到4g以上的地址上去,这个功能是由硬件决定的。也就是我们第一节介绍的
(HECBASE+256M) - (4G-32M) MMIO可分配给外设使用的pci memory空间 为什么要在4G以下设置Low MMIO区域,造成内存被分割成两块,为什么不能把MMIO都放在4G以上?主要还是为了照顾pci 32/64bit的兼容,32bit的pci地址需要放在4G以下的空间。
(4G-32M) - 4G CPU-spec 4G以下的32M区域是CPU的一些特殊区域,主要由以下几部分组成: 1、16M fireware地址; 2、一些直接访问的cpu寄存器; 3、Interrupt、I/O APIC区域;
4G - ram_size 高于4G的常规内存
ram_size - high MMIO 在高端内存之上一直到CPU支持的最大空间,都可以用来映射64bit的pci memory外设地址

上面的介绍已经能够帮助我们理解x86 CPU的地址空间分配了,下面还有另外一张图,也是详细介绍了地址空间分配,不过图中描述的更加细节,不再过多说明