浅析request_mem_region和ioremap函数的理解

在了解这两个函数之前我们首先要明白CPU的寻址。任何一种外设都是通过读写寄存器来控制的,寄存器又通常包括三大类:控制寄存器,状态寄存器和数据寄存器。根据CPU体系的不同,CPU对I/O端口的编址方式分为I/O映射和内存映射两种方式。


(1).I/O映射方式:


     以intel为代表的i386系列处理器中,内存和外部I/O是独立编址独立寻址。即在该体系中存在两种地址空间:内存空间和I/O空间。从处理器的角度来说,i386提供了两种不同的指令分别用来访问I/O地址空间和内存空间,两种指令相互独立。


(2).内存映射方式:


   在嵌入式领域的处理器中,通常只能操作内存地址空间,并没有单独的I/O地址空间可供操作。换句话说该体系中没有单独的I/O指令用来操作外设。这种情况我我们只能通过将I/O端口的物理地址映射到内存空间,从而CPU像访问内存一样访问I/O地址空间。

 

很显然,在s3c2440中是内存映射方式来访问外设。一般来说,外设的I/O物理地址有硬件决定,在datasheet中可以查到相应外设的I/O物理地址。由于CPU不提供单独的指令操作I/O外设,因此驱动程序并不能对其物理地址访问。而必须把它们映射到虚拟地址空间,然后通过操作映射得到的虚拟地址从而实现对I/O资源的操作。request_mem_region和ioremap函数就是实现物理地址到虚拟地址映射的功能。

/* 从 start 开始,分配一个 len 字节的内存区域。成功返回一个非NULL指针,否则返回NULL。所有的 I/O 内存分配情况都 /proc/iomem 中列出。*/
struct resource *request_mem_region(unsigned long start, unsigned long len, char*name);
/*I/O内存区域在不再需要时应当释放*/
void release_mem_region(unsigned long start, unsigned long len); 

/*一个旧的检查 I/O 内存区可用性的函数,不推荐使用*/
int check_mem_region(unsigned long start, unsigned long len);


申请完内存分配后必须设置一个映射,由 ioremap 函数实现,此函数专门用来为I/O 内存区域分配虚拟地址。经过ioremap 之后,设备驱动即可访问任意的 I/O 内存地址。注意:ioremap 返回的地址不应当直接引用;应使用内核提供的 accessor 函数。以下为函数定义:

#include <asm/io.h>
void *ioremap(unsigned long phys_addr, unsigned long size);
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);/*如果控制寄存器也在该区域,应使用的非缓存版本,以实现side effect。*/
void iounmap(void * addr);

总的来说只需记住,对于内存映射方式,操作寄存器之前一定要先申请内存空间,申请之后再建立映射关系。操作结束之后同样要先释放申请的内存空间,再取消映射关系。



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值