linux 内核中的ioremap函数

作者 by adtxl / 2022-04-20 / 暂无评论 / 440 个足迹

版权声明:本文为CSDN博主「小灏灏同学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

Linux kernel version 4.19

1. 基本概念

在编写linux驱动过程中,不可避免的会涉及操作外设,而外设的地址空间与DDR的地址空间一般不连续,在linux上电时,并不会为外设地址空间建立页表,又因为linux访问内存使用的都是虚拟地址,因此如果想访问外设的寄存器(一般包括数据寄存器、控制寄存器与状态寄存器),需要在驱动初始化中将外设所处的物理地址映射为虚拟地址,linux为应对该问题提供了较多接口,包括ioremap/ioremap_wc/devm_ioremap/devm_ioremap_resource等,以应对不同的场景需求,本文 即阐述这些接口的使用,以及需要注意的区别。

在系统运行时,外设IO资源的物理地址是已知的,由硬件的设计决定(参考SOC的datesheet,一般会有memorymap)。驱动程序不能通过物理地址访问IO资源,必须将其映射到内核态的虚拟地址空间(通过页表),然后根据映射所得到的内核虚拟地址范围,通过线性偏移(virt_addr = virt_base + phy_addr - phy_base)访问这些IO内存资源。

2. IO资源映射与解映射

2.1 映射api

// arch/arm/include/asm/io.h
 * ioremap() and friends.
 * ioremap() takes a resource address, and size.  Due to the ARM memory
 * types, it is important to use the correct ioremap() function as each
 * mapping has specific properties.
 * Function     Memory type Cacheability    Cache hint
 * ioremap()        Device      n/a     n/a
 * ioremap_nocache()    Device      n/a     n/a
 * ioremap_cache()  Normal      Writeback   Read allocate
 * ioremap_wc()     Normal      Non-cacheable   n/a
 * ioremap_wt()     Normal      Non-cacheable   n/a
 * All device mappings have the following properties:
 * - no access speculation
 * - no repetition (eg, on return from an exception)
 * - number, order and size of accesses are maintained
 * - unaligned accesses are "unpredictable"
 * - writes may be delayed before they hit the endpoint device
 * ioremap_nocache() is the same as ioremap() as there are too many device
 * drivers using this for device registers, and documentation which tells
 * people to use it for such for this to be any different.  This is not a
 * safe fallback for memory-like mappings, or memory regions where the
 * compiler may generate unaligned accesses - eg, via inlining its own
 * memcpy.
 * All normal memory mappings have the following properties:
 * - reads can be repeated with no side effects
 * - repeated reads return the last value written
 * - reads can fetch additional locations without side effects
 * - writes can be repeated (in certain cases) with no side effects
 * - writes can be merged before accessing the target
 * - unaligned accesses can be supported
 * - ordering is not guaranteed without explicit dependencies or barrier
 *   instructions
 * - writes may be delayed before they hit the endpoint memory
 * The cache hint is only a performance hint: CPUs may alias these hints.
 * Eg, a CPU not implementing read allocate but implementing write allocate
 * will provide a write allocate mapping instead.
void __iomem *ioremap(resource_size_t res_cookie, size_t size);
#define ioremap ioremap
#define ioremap_nocache ioremap


  • ioremap & ioremap_nocache实现相同,使用场景为映射device memory类型内存;
  • ioremap_cached,使用场景为映射normal memory类型内存,且映射后的虚拟内存支持cache;
  • ioremap_wc & ioremap_wt实现相同,使用场景为映射normal memory类型内训,且映射后的虚拟内存不支持cache