日期:2014-05-16 浏览次数:20656 次
我们知道默认外设 I/O 资源是不在 Linux 内核空间中的(如 sram 或硬件接口寄存器等),若需要访问该外设 I/O 资源,必须先将其地址映射到内核空间中来,然后才能在内核空间中访问它。
?
Linux 内核访问外设 I/O 内存资源的方式有两种:动态映射 (ioremap) 和静态映射 (map_desc) 。
?
一、动态映射 (ioremap) 方式
?
动态映射方式是大家使用了比较多的,也比较简单。即直接通过内核提供的 ioremap 函数动态创建一段外设 I/O 内存资源到内核虚拟地址的映射表,从而可以在内核空间中访问这段 I/O 资源。
Ioremap 宏定义在 asm/io.h 内:
#define ioremap(cookie,size)?????????? __ioremap(cookie,size,0)
?
__ioremap 函数原型为 (arm/mm/ioremap.c) :
void __iomem * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags);
phys_addr :要映射的起始的 IO 地址
size :要映射的空间的大小
flags :要映射的 IO 空间和权限有关的标志
该函数返回映射后的内核虚拟地址 (3G-4G). 接着便可以通过读写该返回的内核虚拟地址去访问之这段 I/O 内存资源。
?
举一个简单的例子 : ( 取自 s3c2410 的 iis 音频驱动 )
比如我们要访问 s3c2410 平台上的 I2S 寄存器 , 查看 datasheet 知道 IIS 物理地址为 0x55000000 ,我们把它定义为宏 S3C2410_PA_IIS ,如下: