1、物理地址:很简单的说就是真实存在的地址,芯片固定物理地址即固定,可通过datasheet查询
2、虚拟地址:虚拟的嘛,同一程序在不同时间运行,虚拟地址可能就不同,由系统分配
3、ioremap():将物理地址映射为虚拟地址的linux库函数,可以简单的理解为物理地址通往虚拟地址的桥梁
引入一个问题:后台运行两个相同程序address,其变量地址和mian地址分别都是0X6BC3A0和0X400B5B呢?难道是同一个地址可以保留两个不同的数据吗?
见下图:
当然不是,其实你看到的地址仅仅是系统的虚拟地址而已,其同一个虚拟地址可以对应多个物理地址,也就是说你看到的两个程序地址分别是0X6BC3A00X400B5B,但经过地址映射器后,其两个程序对应的物理地址就不是同一个了;
简单来说:程序想要访问硬件设备必要要经过虚拟地址转换为物理地址。说白了处理器中不仅仅只有CPU,还有MMU(内存管理单元,其内部包含地址映射器,外设片选),外设…这里主要介绍MMU单元,如果程序想要访问相关外设,则CPU首先发出虚拟地址然后通过MMU转换为对应的物理地址,然后MMU通过物理地址找到需要访问的外设设备,再把对应的CS pin拉为有效电平,这样就可以访问到具体的外设设备咯。
简单来说就像下图这样(PS:图片仅供参考,还请各位大佬指正):
简单来说:就是MMU中的地址映射器把CPU传输过来的虚拟地址转换为硬件可识别的物理地址,然后再把这个地址传输给片选单元,片选单元根据地址范围找到对应模块并把片选引脚置为有效信号。
那我们要如何将物理地址转换为虚拟地址呢,当然是通过ioremap函数:
/*ioremap(phys_addr_t paddr, unsigned long size)*/
GPIO5_GDIR = ioremap(0x020AC004,4); //设置GPIO5的方向,其中0x020AC004为GPIO5的方向寄存器,这个地址在datasheet中可以查到。想要访问0x020AC004,必须将这个物理地址转换为虚拟地址后才能供CPU使用
后面就可以直接通过GPIO5_GDIR去设置GPIO5的方向了,这个0x020AC004便是实实在在存在的物理地址,GPIO5_GDIR就是映射后的虚拟地址。
(PS:个人看了视频后的拙见,必有不恰之处,还请各位大佬指正!!!)