日期:2014-05-16  浏览次数:20584 次

Linux内核访问外设I/O资源的方式

我们知道默认外设 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 ,如下: