Linux学习之I/O内存访问详解
来源:互联网 发布:c语言图书管理系统 编辑:程序博客网 时间:2024/06/05 21:13
ARM是对内存空间和IO空间统一编址的,所以,通过读写SFR来控制硬件也就变成了通过读写相应的SFR地址来控制硬件。这部分地址也被称为I/O内存。x86中对I/O地址和内存地址是分开编址的,这样的IO地址被称为I/O端口。本文只讨论linux系统中IO内存的访问。
IO内存访问流程
我们知道,为了管理最重要的系统资源并让物理地址对进程透明,Linux使用了内存映射机制,就是一个进程如果想访问一个物理内存地址(eg.SFR地址),那么首先就是将其映射成虚拟地址。
IO内存申请/归还
Linux提供一组函数用于申请和释放IO内存的范围,这两个API在访问IO内存的时候并不是必须的,但是建议使用,他们可以检查申请的资源是否可用,增加IO访问的安全性,如果可用则申请成功,并标志为已用,其他驱动想在这个进程归还资源前申请就会失败。
request_mem_region()宏函数向内存申请n个内存地址,这些地址从first开始,len长,name表示设备的名称,成功返回非NULL失败返回NULL。
/**
* request_mem_region - create a new busy resource region
* @start: resource start address
* @n: resource region size
* @name: reserving caller's ID string
*/
struct resource * request_mem_region(resource_size_t start, resource_size_t n,const char *name)
release_mem_region()宏函数顾名思义就是将request_mem_region()申请的IO内存资源归还给内核以便其他进程也可以访问该IO内存。
/**
* release_mem_region - release a previously reserved resource region
* @start: resource start address
* @n: resource region size
*/
void release_mem_region(resource_size_t start, resource_size_t n,const char *name)
IO内存映射/去映射
申请了IO资源,接下来就是进行物理地址到虚拟地址的映射。内核提供的API如下
static inline void __iomem *ioremap(unsigned long port, unsigned long size)
static inline void iounmap(volatile void __iomem *addr)
IO内存访问API
ARM的SFR是32bit的,我们在经过了ioremap之后其实就可以直接通过强制类型转换来读取获取的虚拟地址,但是这种方法不够安全,一不小心就会读错位,为此,内核同样提供的标准的API来读写IO内存,不但代码的安全性更高,可读性也得到了改善。
读IO
unsigned int ioread8(void *addr) unsigned int ioread16(void *addr) unsigned int ioread32(void *addr)
写IO
void iowrite8(u8 val,void *addr) void iowrite16(u8 val,void *addr) void iowrite32(u8 val,void *addr)
读一串IO内存
void ioread8_rep(void *addr,void *buf,unsigned long len) void ioread16_rep(void *addr,void *buf,unsignedlong len) void ioread32_rep(void *addr,void *buf,unsigned long len)
写一串IO内存
void iowrite8_rep(void *addr,const void *buf,unsigned long len) void iowrite16_rep(void *addr,const void*buf,unsigned long len) void iowrite32_rep(void *addr,const void *buf,unsigned long len)
复制IO内存
void memcpy_fromio(void *dest,void *source,unsigned long len) void memcpy_toio(void *dest,void*source,unsigned long len)
设置IO内存
void memset_io(void *addr,u8 value,unsigned int len)
来源:51CTO
0 0
- Linux学习之I/O内存访问详解
- Linux学习一 I/O内存分配与I/O访问
- linux 内存和I/O访问
- Linux内存与I/O访问
- linux内存与I/O访问
- linux 内存与I/O访问机制
- Linux 内存与I/O访问
- Linux 内存与I/O访问
- 内核驱动之I/O内存访问
- 内核驱动之I/O内存访问
- 详解linux中I/O端口与I/O内存
- linux驱动学习--第十九天:第十一章:CPU 与内存和I/O(二):设备I/O 端口和I/O 内存的访问
- Linux设备驱动开发详解--笔记11--内存与I/O访问
- 内存与I/O访问
- 内存与I/O访问
- 内存与I/O访问
- 内存与I/O访问
- 内存和I/O访问
- 【t014】拯数
- POJ2425(树形,无向无环图博弈) SG函数
- redis数据库
- SpringMVC文件上传下载
- spark 中 rdd to dataframe 问题
- Linux学习之I/O内存访问详解
- Hive源码调试步骤
- <Linux多线程服务端编程>学习记录
- Java 网络编程简单学习笔记1
- 关于adb
- 72. Edit Distance
- HDU 4876 ZCC loves cards
- ubuntu中配置samba方法
- CentOS中更改IPV4和IPV6地址以及路由