寄存器和ioremap的使用

本文介绍了寄存器的基本概念和类型,特别是在8位、16位及32位系统中的大小。接着深入探讨了Linux内核中的ioremap函数,用于将I/O地址映射到虚拟地址空间,以便驱动程序访问。ioremap使得即使硬件地址未直接映射到虚拟地址,也能进行有效访问。通过ioremap后的地址,可以通过特定的I/O内存读写函数进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、寄存器

1.寄存器概述
寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。

按照功能的不同,可将寄存器分为基本寄存器和移位寄存器两大类。基本寄存器只能并行送入数据,也只能并行输出。移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入、并行输出,也可以串行输入、串行输出,还可以并行输入、串行输出,或串行输入、并行输出,十分灵活,用途也很广。

2.寄存器的大小:
8位的单片机,一个寄存器占8bit,一个字节。16位的单片机,1个寄存器,占16bit,2个字节。高级一点的,arm的芯片,一个寄存器占32bit,即是4个字节。

二、ioremap学习

原型:

void *ioremap(unsigned long phys_addr, unsigned long size)  
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物理地址。映射完了

### mmap ioremap 的区别 #### mmap 函数概述 `mmap()` 是一种用于内存映射文件或设备的系统调用。其函数原型如下[^1]: ```c void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); ``` 此方法允许进程将文件或其它对象映射到自己的地址空间,从而可以通过访问内存来操作这些资源。 #### ioremap 函数概述 相比之下,`ioremap()` 是专为 I/O 内存区域设计的一个宏,在 Linux 内核中定义。该宏的作用是把物理地址转换成可以由 CPU 访问的虚拟地址。通常情况下,这适用于 PCI 配置寄存器或其他外围设备上的 MMIO(Memory-Mapped I/O)。具体实现形式可能因架构而异,但在 x86 架构下一般形似于下面的形式: ```c #include <asm/io.h> void __iomem *ioremap(resource_size_t offset, unsigned long size); ``` #### 使用场景对比 - **适用范围** `mmap()` 主要应用于用户态程序对常规文件系统的交互;而对于内核模块来说,则更多地利用 `ioremap()` 来处理特定硬件接口的操作。 - **权限控制** 当使用 `mmap()` 映射时,需要考虑文件描述符以及相应的保护标志 (`prot`) 参数设置,以确保正确的读写权限管理。然而对于 `ioremap()`, 它主要用于映射那些已经存在于系统中的固定位置的 I/O 资源,并不需要额外指定类似的参数来进行权限配置。 - **性能考量** 对于频繁的数据交换而言,直接通过 `mmap()` 进行零拷贝传输可能会带来更好的效率提升。但是当涉及到专用外设通信时,采用 `ioremap()` 可能更加高效稳定,因为它绕过了缓存一致性等问题带来的复杂度。 - **清理工作** 在不再需要之前创建好的映射关系之后,应当分别调用对应的解除映射函数:针对 `mmap()` 应该使用 `munmap()` ,而对于经由 `ioremap()` 建立起来的地图则需借助 `iounmap()` 完成释放动作。 ```c int munmap(void *addr, size_t length); void iounmap(volatile void __iomem *addr); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值