Linux 对处理器物理地址/虚拟地址和ioremap函数的个人理解

写在前面

在Linux驱动学习过程中,遇到了ioremap这个函数,参数是phy_addr,返回值是虚拟地址。 linux启动以后,由于mmu的存在,想要控制寄存器,要找到寄存器物理地址的虚拟地址映射(听着比较拗口)。
前几天遇到了一个问题,手上的板子是rk3399,64bit的cpu,ram是2GB。spi3寄存器的base addr是0xff350000, 通过ioremap函数可以找到spi3 base addr的virtual add,但是0xff35000已经超过了ram的2GB,这个物理地址到底是什么地址。 原来一直任务cpu的物理地址指的是ram。
查找资料,发现原来对cpu的地址理解有很大的误区。

个人理解

  1. cpu的寻址大小是与本身是32位还是64位有关。
  2. 寄存器地址就是物理地址,ram地址也是物理地址,ram的物理地址是固定的,大小受存储控制器控制
  3. 关于内存映射,也就是mmu,不仅映射ram这个存储的地址,还映射了寄存器的存储地址(寄存器是存放在ram之外的存储设备里面的)
  4. arm的可寻址空间的地址可以使用,也可以不使用,哪些物理地址代表什么,是cpu厂商去定义的。

错误分析

举个例子, ioremap(0xff350000, flags); 这个0xff350000是rk3399的spi3寄存器的地址。 我一直在疑惑,程序是运行在内存上面的,我们的内存是2G的,0xff350000超过了3G,这怎么可能。
出现这个疑惑的原因,是因为我一直以为mmu的内存映射仅仅映射mmu,其实寄存器存储器也被映射了。 所以ioremap(0xff350000, flags)的意思是,找到0xff350000的虚拟地址,这个地址实际上是存在的,只是不在ram存储器上,是在寄存器存储器上。

我原来的错误是
1. 认为mmu只映射ram
2. 寄存器也是有存储空间的
3. 物理地址就是cpu可寻的地址,可以使用,也可以不适用
4. 寄存器物理地址的是厂商定义的,这个不用纠结

你可能感兴趣的:(linux/memory)