默认外设I/O资源不在Linux内核空间中的,如sram或硬件接口寄存器等),若需要访问该外设I/O资源,必须先将其地址映射到内核空间中来,然后才能在内核空间中访问它。Linux内核访问外设I/O方式有两种:动态映射(ioremap)和静态映射(map_desc)。
一、动态映射Ioremap
ioremap函数返回映射后的内核虚拟地址(3G-4G). 接着便可以通过读写该返回的内核虚拟地址去访问之这段I/O内存资源。
举例:
比如我们要访问s3c2410平台上的I2S寄存器, 查看datasheet 知道IIS物理地址为0x55000000,我们把它定义为宏S3C2410_PA_IIS,如下:
#define S3C2410_PA_IIS (0x55000000)
若要在内核空间(iis驱动)中访问这段I/O寄存器(IIS)资源需要先建立到内核地址空间的映射:
our_card->regs = ioremap(S3C2410_PA_IIS, 0x100);
if (our_card->regs == NULL) {
err = -ENXIO;
goto exit_err;
}
创建好了之后,我们就可以通过readl(our_card->regs )或writel(value, our_card->regs)等IO接口函数去访问它。
二、静态映射(map_desc)方式
内核提供了在系统启动时通过map_desc结构体静态创建I/O资源到内核地址空间的线性映射表(即page table)的方式,这种映射表是一种一一映射的关系。程序员可以自己定义该I/O内存资源映射后的虚拟地址。创建好了静态映射表,在内核或驱动中访问该I/O资源时则无需再进行ioreamp动态映射,可以直接通过映射后的I/O虚拟地址去访问它。一次映射,多次访问。
http://blog.chinaunix.net/uid-12617001-id-3767393.html
http://blog.csdn.net/liuxd3000/article/details/16819921