ioremap

原型: 

 
 
  1. void *ioremap(unsigned long phys_addr, unsigned long size)  
  2. void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)  

入口: phys_addr:要映射的起始的IO地址;

  size:要映射的空间的大小;

          ioremap 依靠 __ioremap实现,它只是在__ioremap中以第三个参数为0调用来实现.

  flags:要映射的IO空间的和权限有关的标志;

          phys_addr:是要映射的物理地址,

          size:是要映射的长度,

功能:将一个IO地址空间映射到内核的虚拟地址空间上去,便于访问;函数专门用来为I/O内存区域分配虚拟地址。经过ioremap之后,设备驱动即可访问任意的I/O内存地址。有了ioremap (和iounmap),设备就可以访问任何I/O内存空间,不论它是否直接映射到虚拟地址空间。但是,这些地址永远不能直接使用(指物理地址),而要用readb这种函数。

    ioremap是内核提供的用来映射外设寄存器到主存的函数,我们要映射的地址来源于CPU的用户开发手册。硬件的跳线或者是物理连接方式决定了硬件上的内存映射到的cpu物理地址。映射完了有什么效果呢,举个例子,比如某个网卡有100个寄存器,他们都是连在一块的,位置是固定的,加入每个寄存器占4个字节,那么一共400个字节的空间被映射到内存成功后,ioaddr就是这段地址的开头(ioaddr = ioremap (mmio_start, mmio_len);注意ioaddr是虚拟地址,而mmio_start是物理地址,它是开发手册中提供的,肯定是物理地址,而保护模式下CPU不认物理地址,只认虚拟地址),ioaddr+0就是第一个寄存器的地址,ioaddr+4就是第二个寄存器地址(每个寄存器占4个字节),以此类推,我们就能够在内存中访问到所有的寄存器进而操控他们了。

    访问I/O内存的正确方式是通过一系列专用于此目的的函数(在<asm/io.h>中定义的):

/*I/O内存读函数*/ 

  1. unsigned int ioread8(void*addr); 
  2. unsigned int ioread16(void*addr);
  3.  unsigned int ioread32(void*addr); 
  4. /*addr是从ioremap获得的地址(可能包含一个整型偏移量),返回值是从给定I/O内存读取的值*/

 /*对应的I/O内存写函数*/

 
 
  1. void iowrite8(u8value,void*addr); 
  2. void iowrite16(u16value,void*addr);
  3. void iowrite32(u32value,void*addr); 

/*读和写一系列值到一个给定的I/O内存地址,从给定的buf读或写count个值到给定的addr*/

 
 
  1. void ioread8_rep(void *addr, void *buf, unsigned long count); 
  2. void ioread16_rep(void *addr, void *buf, unsigned long count); 
  3. void ioread32_rep(void *addr, void *buf, unsigned long count); 
  4. void iowrite8_rep(void *addr, const void *buf, unsigned long count); 
  5. void iowrite16_rep(void *addr, const void *buf, unsigned long count); 
  6. void iowrite32_rep(void *addr, const void *buf,unsigned long count); 

/*需要操作一块I/O地址,使用一下函数*/

 
 
  1. void memset_io(void *addr, u8 value, unsigned int count); 
  2. void memcpy_fromio(void *dest,void *source, unsigned int count); 
 
 
  1. void memcpy_toio(void *dest, void *source, unsigned int count) 

/*旧函数接口,仍可工作,但不推荐。*/

 
 
  1. unsigned readb(address); 
  2. unsigned readw(address); 
  3. unsigned readl(address); 
  4. void writeb(unsigned value,address); 
  5. void writew(unsigned value,address); 
  6. void writel(unsigned value,address); 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值