欢迎来到天天文库
浏览记录
ID:39465474
大小:79.00 KB
页数:10页
时间:2019-07-04
《Linux内核访问外设IO资源的方式》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、Linux内核访问外设I/O资源的方式Linux内核访问外设I/O资源的方式 Author:DongasDate:08-08-02 我们知道默认外设I/O资源是不在Linux内核空间中的(如sram或硬件接口寄存器等),若需要访问该外设I/O资源,必须先将其地址映射到内核空间中来,然后才能在内核空间中访问它。 Linux内核访问外设I/O内存资源的方式有两种:动态映射(ioremap)和静态映射(map_desc)。 一、动态映射(ioremap)方式 动态映射方式是大家使用了比较多的,也比较简单。
2、即直接通过内核提供的ioremap函数动态创建一段外设I/O内存资源到内核虚拟地址的映射表,从而可以在内核空间中访问这段I/O资源。Ioremap宏定义在asm/io.h内:#defineioremap(cookie,size) __ioremap(cookie,size,0) __ioremap函数原型为(arm/mm/ioremap.c):void__iomem*__ioremap(unsignedlongphys_addr,size_tsize,unsignedlongfla
3、gs);phys_addr:要映射的起始的IO地址size:要映射的空间的大小flags:要映射的IO空间和权限有关的标志该函数返回映射后的内核虚拟地址(3G-4G).接着便可以通过读写该返回的内核虚拟地址去访问之这段I/O内存资源。 举一个简单的例子:(取自s3c2410的iis音频驱动)比如我们要访问s3c2410平台上的I2S寄存器,查看datasheet知道IIS物理地址为0x55000000,我们把它定义为宏S3C2410_PA_IIS,如下:#defineS3C2410_PA_IIS
4、(0x55000000)若要在内核空间(iis驱动)中访问这段I/O寄存器(IIS)资源需要先建立到内核地址空间的映射:our_card->regs=ioremap(S3C2410_PA_IIS,0x100);if(our_card->regs==NULL){ err=-ENXIO; gotoexit_err;}创建好了之后,我们就可以通过readl(our_card->regs)或writel(value,our_card->regs)等IO接口函数去访问它。 二、静态
5、映射(map_desc)方式 下面重点介绍静态映射方式即通过map_desc结构体静态创建I/O资源映射表。内核提供了在系统启动时通过map_desc结构体静态创建I/O资源到内核地址空间的线性映射表(即pagetable)的方式,这种映射表是一种一一映射的关系。程序员可以自己定义该I/O内存资源映射后的虚拟地址。创建好了静态映射表,在内核或驱动中访问该I/O资源时则无需再进行ioreamp动态映射,可以直接通过映射后的I/O虚拟地址去访问它。 下面详细分析这种机制的原理并举例说明如何通过这种静态映
6、射的方式访问外设I/O内存资源。 内核提供了一个重要的结构体structmachine_desc,这个结构体在内核移植中起到相当重要的作用,内核通过machine_desc结构体来控制系统体系架构相关部分的初始化。machine_desc结构体的成员包含了体系架构相关部分的几个最重要的初始化函数,包括map_io,init_irq,init_machine以及phys_io,timer成员等。machine_desc结构体定义如下:structmachine_desc{ /* *Note
7、!Thefirstfourelementsareused *byassemblercodeinhead-armv.S */ unsignedint nr; /*architecturenumber */ unsignedint phys_io; /*startofphysicalio */ unsignedint io_pg_offst; /*byteoffsetforio
8、 *pagetabeentry */ constchar *name; /*architecturename */ unsignedlong boot_params; /*taggedlist */ unsignedint video_start; /*startofvideoRAM */ unsignedint
此文档下载收益归作者所有