1 逻辑地址
逻辑地址是最为模糊的概念。
《understanding the linux kernel》上的解释是与虚拟地址相关,基于硬件MMU与软件内存管理的一个概念,具体可以看UTLK的第二章内存寻址,有很详细的解释。
但是工作中之前用到的MIPS架构的处理器的解释却有出入,在《MIPS体系架构透视》一书中,逻辑地址是跟MMU无关的,MIPS地址空间划分中,Kseg0 Kseg1地址空间与真实的物理地址存在一个偏移量,也就是存在线性关系,是一种“简单的无须转换翻译”的关系。
同一块内存被分别线性映射到这2个地址空间中,无论处理器有无MMU单元,上电这2个地址空间就是划分好的(2个地址空间区别在于是否默认开启缓存)。
对于MIPS处理器逻辑地址的划分肯定是由其内部逻辑电路来处理,不需MMU。
2 虚拟地址
虚拟地址做为程序员应该听说的最多,不管是在linux还是windows下编程,程序所操作地址都是虚拟地址。
虚拟地址是硬件MMU与软件内存管理结合的产物,方便更高效率的使用RAM。内存管理是篇大文章,这里就不聊细节了,具体可以看UTLK的内存寻址一章。
逻辑地址 虚拟地址作为软件开发人员在基于系统编程以及裸编下都会操作到。
3 物理地址
对于嵌入式开发,物理地址是必须明白的,物理地址是指处理器芯片发出,来进行地址空间寻址的地址,它与处理器地址引脚上发出的电信号相对应。
UTLK上说用于内存芯片级的单元寻址,真实的开发环境中不止这些,因为处理器外部除了RAM还需要别的外设,如nand, spi,serial(当然是指的这些外设的controller)等。
物理地址是处理器真实发送到其地址总线上的地址,而该地址应该访问到谁(ram controller?nand controller?),这个需要看该设备系统总线的仲裁,也就是总线仲裁,现在常用的总线仲裁有AXI AHBA等。
这些总线仲裁器来规划处理器的物理地址空间。
大部分处理器手册会给出其address map,也就是外设控制器(寄存器)在该处理器地址空间上的分布情况。
对于处理器来说,虚拟地址 逻辑地址都是一个输入源,处理器对这些地址进行转换(比如利用MMU),转换为物理地址,真正处理器发出的地址是物理地址。
4 总线地址
总线地址是最难理解的一个概念。
所有的地址都可以称为总线地址,因为开发环境下所有的设备都是接在总线上,如AXI总线,APB总线,PCI总线 I2C总线 SPI总线。也就会存在很多种地址空间。
大部分情况下,总线地址=物理地址,为什么呢,物理地址是处理器在该系统总线上发出的地址,因此处理器发出的物理地址完全可以理解为处理器地址空间的总线地址,这肯定是相等的。
大部分程序操作都是处理器作为主设备,根据指令,来发出地址,读写数据。这时总线地址=物理地址
有一种情况下不是处理器做主设备,DMA,DMA controller操作RAM是不需要经过处理器的,这是DMA controller是主设备,但是因为DMA controller也是挂接在系统总线上,也就是处理器的地址空间中。
所以这时DMA controller发出的地址也是物理地址。
有一种特殊情况下,总线地址与物理地址不同,就是PCI总线。
因为PCI总线存在地址映射,这是因为PCI控制器内部有桥接电路,桥接电路会将I/O地址映射为不同的物理地址。
可以想象,PCI控制器挂接在处理器的系统总线上,而另一端的PCI总线上外扩了一些PCI设备。
假如某个PCI设备具有DMA能力,要去操作RAM,这时该设备看到的RAM的地址就应该是由系统总线映射到PCI总线上的总线地址。
映射关系由PCI控制器地址窗口来配置,一般是一个偏移量,所以这时映射到PCI总线上的RAM的总线地址就不是RAM在处理器系统地址空间上的物理地址(也可以称为系统总线地址)了。
因此总线地址 != 物理地址。
当然PCI控制器地址窗口可以配置为平映射,这时总线地址就跟物理地址相同了。
这时还会想到一点问题,那像I2C总线 SPI总线会不会也有这样的问题,其实多虑了,PCI总线存在这个问题,是因为PCI总线支持设备做主设备,进行DMA。
而I2C SPI总线不具有这样的能力,但是他们还是有各自的地址空间,因此我们在操作I2C SPI总线时需要在其数据线上根据协议来发送地址锁定设备的。这个地址就不是处理器地址空间了,而是相应总线的地址空间了。
经过上面的解释,可以看出,任何开发环境都存在很多地址总线(AXI PCI I2C SPI),也就有很多地址空间。
物理地址也是总线地址,只不过是处理器系统总线地址(如AXI AHBA等)罢了。