版权声明:本文为CSDN博主「小灏灏同学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/student456852/article/details/116868447
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 & ioremap_nocache实现相同,使用场景为映射device memory类型内存;
- ioremap_cached,使用场景为映射normal memory类型内存,且映射后的虚拟内存支持cache;
- ioremap_wc & ioremap_wt实现相同,使用场景为映射normal memory类型内训,且映射后的虚拟内存不支持cache
https://blog.csdn.net/zqixiao_09/article/details/50859505
https://blog.csdn.net/student456852/article/details/116868447
https://blog.csdn.net/student456852/article/details/116853107
评论