(转)CPU地址空间小结

地址空间的映射


这里要说的是Intel构架下的CPU地址空间布局,注意这里没有说是内存地址空间布局。

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

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


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


上图中左边是地址空间,右边是DRAM空间,其中红色的字体表示寄存器,可以在spec中找到该寄存器的说明,这几个寄存器决定了整个地址空间的大的格局。这里就简要说明一下。

      TOLUD,指向32位地址,也就是4GB以内。它是一个分界线,在0-TOLUD之间为DRAM,TOLUD-4GB之间为MMIO空间。该值由BIOS指定。为了方便说明,假设TOLUD被指定为2GB。

      TOM,目前还不明确,我猜想应该是指实际物理内存的大小,“the total amount of populated physical
memory”,比如上图TOM为5GB。可在本机的BDFR(0,0,0,A0)验证。

      REMAPBASEREMAPLIMIT,也是36位,分别表示基址和上限地址。用于重映射DRAM中被MMIO遮住的一部分空间,有2GB。该图中将DRAM中遮住的部分重映射到TOM的上方,所以REMAPBASE为5GB,REMAPLIMIT为7GB-1。

      TOUUD,36位地址,大小为REMAPLIMIT+1的位置,比如上图TOUUD应该在7GB的位置,可以和TOLUD做对比理解,TOLUD是4GB以内DRAM与MMIO的分界线,TOUUD可以理解为4GB-64GB之间DRAM与MMIO的分界线。


      以上是假设DRAM超出4GB的情况,假如DRAM只有3GB,而TOLUD指定为2GB呢?也就是2GB-3GB的DRAM被遮住。这时也是通过REMAPBASE和REMAPLIMIT将之重定向到4GB的上方。再假设DRAM只有2GB,TOLUD为2GB呢?这时就不存在重映射。 REMAPLIMIT小于REMAPBASE时(通常REMAPLIMIT为0),表示不使用重映射。



1.物理内存,在不引起误解的情况下,是指非专业人士、专业人士都懂的——内存条,比如SDRAM、DDR/DDR2/DDR3/DDR4/DDR5等内存条。 

2.虚拟地址(如果存在的话,见后面4)是程序员视角的地址,比如C语言中的指针值,汇编程序员使用CPU指令产生的寻址。

3.物理地址是CPU芯片地址引脚(假定内存控制器没有集成在CPU中)发出的访存地址,物理地址还要被内存控制机构(一般在北桥芯片中)进行译码或映射(映射的一个例子见本文最后17部分提到的“物理内存回收”),可能实际指向DRAM(就是前面提到的内存条),也可能通过一些外部总线(比如PCI)指向各种外部设备。对外部设备的这种访问一般也称为MMIO:Memory Mapped I/O——内存映射I/O。另外特别提一下,x86支持用I/O指令(IN、OUT)寻址的另外的独立64K I/O地址空间,该地址空间不要和这里物理内存地址混淆。

4.  综合前面:逻辑地址(经段转换到)-->线性地址(如果分页使能就是虚拟地址,此时虚拟地址经分页映射到)-->物理地址(经译码转换到)-->内存条上的物理内存地址或MMIO地址。


一般来说,在系统运行时,外设的I/O内存资源的物理地址是已知的(通过request_mem_region()),由硬件的设计决定。但是CPU通常并没有为这些已知的外设I/O内存资源的物理地址 预定义虚拟地址范围,驱动程序并不能直接通过物理地址访问I/O内存资源,而必须将它们映射到核心虚地址空间内(通过页表),然后才能根据映射所得到的核 心虚地址范围,通过访内指令访问这些I/O内存资源。Linux在io.h头文件中声明了函数ioremap(),(在内核驱动程序的初始化阶段,通过ioremap()将物理地址映射到内核虚拟空间(3GB-4GB);在驱动程序的mmap系统调用中,使用remap_page_range()将该块ROM映射到用户虚拟空间。这样内核空间和用户空间都能访问这段被映射后的虚拟地址。)


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值