物理地址上并非全部指向物理内存,除内存外一些物理地址还对应着PCI设备存储(例如显存),一些地址还被保留以便在运行时有新设备插入时分配给它们用。
按一直以来存在的浅层理解,物理地址就是机器内存中的存储位置。假如计算机有32GB内存,那么其物理地址应该是[0, 0x800000000]这个范围。
但是看pcileech项目的时候,发现系统有一个Physical Range的概念,可以用RamMap工具查看。对于我的32GB内存的机器,结果如下
可以看到物理地址都跑到0x81E300000上了,明显大于上述的预期范围。如果认为在上述范围内的物理地址指向了物理内存(也就是机器上的内存条),那其他的地址为什么要空出来呢?
打开windows设备管理器,"查看"页面下面选择"按连接列出资源",看到结果如下
这里面可以看到上面空出的物理地址空间中被什么占用了,例如在“输入/输出”项目里面的内容,占据了[0, 0x10000]的全部空间,正好和Physical Range图中对应上了。把这些项目展开,可以看到细则
也就是说这些主板上的资源占据了一部分物理内存。
PCI线上的显卡中的显存,也会占据物理地址,在这里
显卡可能仅把一部分显存映射到了物理地址空间,所以图中的地址容量加起来可能会小于总显存(12GB)。
物理地址空间对于各个设备和内存和映射关系应该是动态的。例如我在目前的地址分配基础上,关机,拔下显卡并插入一张显存更大的卡(假设100GB),那原先给显存留下的空间就明显不足了,此时重启开机后物理地址的映射关系一定会发生变化。当然,如果机器设备情况没有明显变动,那么映射关系应该也不会无缘故地自己发生变化。
另外,假如某些设备支持热插拔,那么其映射关系应该也会在系统运行时发生变化。这个仅是猜测。
之前的理解,32位机器因为其地址仅能覆盖4GB空间,因此其支持的最大物理内存大小应该是4GB。但结合上文,在一些情况下32位机器能用的物理地址会更少。
这是因为32位的物理地址除了分配给物理内存以外还需要分给其他的设备,例如显存。这个时候如果我依然插入一张12GB显存的显卡,那么它或多或少也要占用一片物理地址。假如这些类似的设备占用了1GB的空间(其中显存应该是大头),那么实际留给物理内存的地址空间就只有3GB了。所以说32位机器插入4GB的内存,也是不能完全使用内存空间的。