本篇文章主要是在ioremap_nocache函数说明的基础上进行整理,加入该函数的用法简介。
函数原型
void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
/*
* ioremap - map bus memory into CPU space
* @offset: bus address of the memory
* @size: size of the resource to map
*
* ioremap performs a platform specific sequence of operations to
* make bus memory CPU accessible via the readb/readw/readl/writeb/
* writew/writel functions and the other mmio helpers. The returned
* address is not guaranteed to be usable directly as a virtual
* address.
*/
调用ioremap_nocache()
函数之后,返回一个线性地址,此时CPU 可以访问设备的内存(已经将其映射到了线性地址空间中了),此时CPU可以使用访问内存的指令访问设备的内存空间,此时我们就可以像访问内存一样来访问设备的内存(寄存器)。
ioremap
是为一段高端的物理内存建立映射(即增加相关的页表内容),驱动常用mmap为可能不连续的一系列逻辑上相关的(如整体是一个文件)物理内存段建立映射,并呈现一个连续的虚拟地址空间。
应用程序常用mmap是系统调用,只能应用程序用。
ioremap是kernel提供的函数,只能在kernel里用。
用法
以下示例以读写基地址为0x9C016000,offset为0x100的寄存器为例。
// 全局定义两个变量
static void __iomem *vaddr_base;
volatile u32 rw32;
// 从物理地址 0x9C016000 开始映射 0x200 大小给虚拟地址 vaddr_base
// 只执行一次
vaddr_base = ioremap_nocache(0x9C016000, 0x200);
// 读写0x9C016000+0x100寄存器bit24~bit27为0001
rw32 = *(volatile u32*)(vaddr_base + 0x100); // 读
printk("Reg0x%x = 0x%x\n", 0x9C016000 + 0x100, rw32);
rw32 &= 0xf0ffffff;
rw32 |= 0x01000000;
*(volatile u32*)(vaddr_base + 0x100) = rw32; // 写
iounmap(vaddr_base);