linx系统内核中ioremap映射分析.docVIP

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
linx系统内核中ioremap映射分析

linux系统内核中ioremap映射分析 几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器、状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址。根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: (1)I/O映射方式(I/O-mapped)   典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为I/O地址空间或者I/O端口空间,CPU通过专门的I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元。 (2)内存映射方式(Memory-mapped) RISC指令系统的CPU(如ARM、PowerPC等)通常只实现一个物理地址空间,外设I/O端口成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。 但是,这两者在硬件实现上的差异对于软件来说是完全透明的,驱动程序开发人员可以将内存映射方式的I/O端口和外设内存统一看作是I/O内存资源。   一般来说,在系统运行时,外设的I/O内存资源的物理地址是已知的,由硬件的设计决定。但是CPU通常并没有为这些已知的外设I/O内存资源的物理地址预定义虚拟地址范围,驱动程序并不能直接通过物理地址访问I/O内存资源,而必须将它们映射到核心虚地址空间内(通过页表),然后才能根据映射所得到的核心虚地址范围,通过访内指令访问这些I/O内存资源(也即是我们可以像读写RAM那样直接读写I/O内存(外设寄存器)资源了)。   为了配置寄存器,我们需要知道寄存器在操作系统中的虚拟地址,因为驱动中要使用的是虚拟地址而非物理地址。在s3c2410中获得GPIO各个寄存器的方法有两种。 第一种是静态映射法:使用系统初始化已经设置好的虚拟地址,这种方法在操作系统启动过程中,页表已经生成,可以直接使用,这时候可以使用内核导出函数在arch/arm/plat-s3c24xx/Gpio.c s3c2410_gpio_cfgpin s3c2410_gpio_getcfg s3c2410_gpio_setpin s3c2410_gpio_getpin等函数配置寄存器GPIO引脚功能 以setpin函数为例: void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) { void __iomem *base = S3C24XX_GPIO_BASE(pin); /*算出端口所在组虚拟基址*/ unsigned long offs = S3C2410_GPIO_OFFSET(pin); /*算出端口所在组的偏移量(0-31)*/ unsigned long flags; unsigned long dat; local_irq_save(flags); dat = __raw_readl(base + 0x04); /*基址 + 0x04为DAT寄存器 */ dat = ~(1 offs); dat |= to offs; __raw_writel(dat, base + 0x04); local_irq_restore(flags); } 分析代码: void __iomem *base = S3C24XX_GPIO_BASE(pin); //定义一个指向所要配置的控制寄存器的基地址的指针,并赋初值(是个虚拟地址) /* #define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x) #define S3C2410_GPIO_BASE(pin) ((((pin)~31)1)+ S3C24XX_VA_GPIO) #define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO-S3C24XX_PA_UART)+ S3C24XX_VA_UART) #define S3C24XX_VA_UART S3C_VA_UART #define S3C_VA_UART S3C_ADDR(0 #define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) #define S3C_ADDR_BASE (0xF4000000) */ __iomem是linux2.6.9内核中加入的特性。是用来个表示指针是指向一个I/O的内存空间。主要是为了驱动程序的通用性考虑。由于不同的CPU体系结构对I/O空间的表示可能不同。当使用__iomem时,编译器会忽略对变量的检查(因为用的是void __iomem)。若要对它进行检查,当__iomem的指针和正常的指针混用时,就会发出一些警告

文档评论(0)

ipad0d + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档