Linux驱动技术(二) _访问I/O内存

简介:

ARM是对内存空间和IO空间统一编址的,所以,通过读写SFR来控制硬件也就变成了通过读写相应的SFR地址来控制硬件。这部分地址也被称为I/O内存。x86中对I/O地址和内存地址是分开编址的,这样的IO地址被称为I/O端口。本文只讨论IO内存的访问。

IO内存访问流程

我们知道,为了管理最重要的系统资源并让物理地址对进程透明,Linux使用了内存映射机制,就是一个进程如果想访问一个物理内存地址(eg.SFR地址),那么首先就是将其映射成虚拟地址。  

IO内存访问流程

IO内存申请/归还

Linux提供一组函数用于申请和释放IO内存的范围,这两个API在访问IO内存的时候并不是必须的,但是建议使用,他们可以检查申请的资源是否可用,增加IO访问的安全性,如果可用则申请成功,并标志为已用,其他驱动想在这个进程归还资源前申请就会失败。

request_mem_region()宏函数向内存申请n个内存地址,这些地址从first开始,len长,name表示设备的名称,成功返回非NULL失败返回NULL。


  
  
  1. /** 
  2.  * request_mem_region - create a new busy resource region 
  3.  * @start: resource start address 
  4.  * @n: resource region size 
  5.  * @name: reserving caller's ID string 
  6.  */ 
  7.  
  8. struct resource * request_mem_region(resource_size_t start, resource_size_t n,const char *name 

release_mem_region()宏函数顾名思义就是将request_mem_region()申请的IO内存资源归还给内核以便其他进程也可以访问该IO内存。


  
  
  1. /** 
  2.  * release_mem_region - release a previously reserved resource region 
  3.  * @start: resource start address 
  4.  * @n: resource region size 
  5.  */ 
  6.  
  7. void release_mem_region(resource_size_t start, resource_size_t n,const char *name 

IO内存映射/去映射

申请了IO资源,接下来就是进行物理地址到虚拟地址的映射。内核提供的API如下


  
  
  1. static inline void __iomem *ioremap(unsigned long port, unsigned long size

  
  
  1. static inline void iounmap(volatile void __iomem *addr) 

IO内存访问API

ARM的SFR是32bit的,我们在经过了ioremap之后其实就可以直接通过强制类型转换来读取获取的虚拟地址,但是这种方法不够安全,一不小心就会读错位,为此,内核同样提供的标准的API来读写IO内存,不但代码的安全性更高,可读性也得到了改善。

读IO


  
  
  1. unsigned int ioread8(void *addr) 
  2. unsigned int ioread16(void *addr) 
  3. unsigned int ioread32(void *addr) 

写IO


  
  
  1. void iowrite8(u8 val,void *addr) 
  2. void iowrite16(u8 val,void *addr) 
  3. void iowrite32(u8 val,void *addr) 

读一串IO内存


  
  
  1. void ioread8_rep(void *addr,void *buf,unsigned long len) 
  2. void ioread16_rep(void *addr,void *buf,unsigned long len) 
  3. void ioread32_rep(void *addr,void *buf,unsigned long len) 

写一串IO内存


  
  
  1. void iowrite8_rep(void *addr,const void *buf,unsigned long len) 
  2. void iowrite16_rep(void *addr,const void *buf,unsigned long len) 
  3. void iowrite32_rep(void *addr,const void *buf,unsigned long len) 

复制IO内存


  
  
  1. void memcpy_fromio(void *dest,void *source,unsigned long len) 
  2. void memcpy_toio(void *dest,void *source,unsigned long len) 

设置IO内存


  
  
  1. void memset_io(void *addr,u8 value,unsigned int len)  





本文作者:佚名
来源:51CTO
目录
相关文章
|
2月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
180 6
|
11天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
35 4
|
14天前
|
算法 Linux 开发者
深入探究Linux内核中的内存管理机制
本文旨在对Linux操作系统的内存管理机制进行深入分析,探讨其如何通过高效的内存分配和回收策略来优化系统性能。文章将详细介绍Linux内核中内存管理的关键技术点,包括物理内存与虚拟内存的映射、页面置换算法、以及内存碎片的处理方法等。通过对这些技术点的解析,本文旨在为读者提供一个清晰的Linux内存管理框架,帮助理解其在现代计算环境中的重要性和应用。
|
20天前
|
存储 缓存 监控
|
26天前
|
缓存 算法 数据处理
如何选择合适的内存访问模式
【10月更文挑战第20天】如何选择合适的内存访问模式
38 1
|
28天前
|
存储 容器
内存越界访问(Out-of-Bounds Access)
【10月更文挑战第12天】
137 2
|
28天前
|
Rust 编译器
|
1月前
|
存储 缓存 监控
Linux中内存和性能问题
【10月更文挑战第5天】
39 4
|
1月前
|
算法 Linux
Linux中内存问题
【10月更文挑战第6天】
46 2
|
17天前
|
缓存 算法 Linux
Linux内核中的内存管理机制深度剖析####
【10月更文挑战第28天】 本文深入探讨了Linux操作系统的心脏——内核,聚焦其内存管理机制的奥秘。不同于传统摘要的概述方式,本文将以一次虚拟的内存分配请求为引子,逐步揭开Linux如何高效、安全地管理着从微小嵌入式设备到庞大数据中心数以千计程序的内存需求。通过这段旅程,读者将直观感受到Linux内存管理的精妙设计与强大能力,以及它是如何在复杂多变的环境中保持系统稳定与性能优化的。 ####
24 0