一、ioremap函数
ioremap 函数用于获取指定物理地址空间对应的虚拟地址空间:
#define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) void __iomem * __arm_ioremap(phys_addr_t phys_addr, size_t size, unsigned int mtype)
{ return arch_ioremap_caller(phys_addr, size, mtype, __builtin_return_address(0));
}
phys_addr:要映射给的物理起始地址。
size:要映射的内存空间大小。
mtype:ioremap 的类型,可以选择 MT_DEVICE、MT_DEVICE_NONSHARED、MT_DEVICE_CACHED 和 MT_DEVICE_WC,ioremap 函数选择 MT_DEVICE。
返回值:__iomem 类型的指针,指向映射后的虚拟空间首地址。
#define SW_MUX_GPIO1_IO03_BASE (0X020E0068)
static void __iomem* SW_MUX_GPIO1_IO03;
SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE, 4);
二、驱动中操作物理绝对地址为什么要先ioremap?
因为在启用 MMU(内存管理单元)后,内核中操作的都是虚拟地址,内核访问不到物理地址,只能通过ioremap映射为虚拟地址,内核才能访问此内存空间。
MMU 主要完成的功能如下:
①、完成虚拟空间到物理空间的映射。
②、内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性。
三、为什么需要将物理地址映射为虚拟地址?
-
隔离:每个进程都认为它拥有全部物理内存。这样每个进程就可以独立运行,不会相互影响。
-
隐藏内存细节:进程不需要知道实际的物理内存布局,它只需要操作虚拟地址空间。
-
可扩展性:虚拟地址空间可以设置得比实际物理内存大很多,这样内存就可以逻辑上看起来更大。
-
便利性:可以在程序运行时重映射虚拟地址,实现共享库、内存管理等功能。
-
存储保护:可以将不同进程的虚拟地址空间设置得不重叠,这样实现地址空间的隔离和存储保护。