Linux内核中ioremap映射的透彻理解

本文探讨了外部设备通过I/O映射和内存映射方式与CPU交互的原理,重点介绍了Linux系统中使用ioremap()和iounmap()函数进行I/O内存资源映射的过程。

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

参考链接:https://www.linuxidc.com/Linux/2011-04/34295.htm

物理地址、总线地址、虚拟地址:https://www.cnblogs.com/rptgba/articles/4549945.html

 

几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器状态寄存器数据寄存器三大类,外设的寄存器通常被连续地编址。根据CPU体系结构的不同,CPU对IO端口的编址方式有两种:

  (1)I/O映射方式(I/O-mapped)

  典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为"I/O地址空间"或者"I/O端口空间",CPU通过专门的I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元。

  (2)内存映射方式(Memory-mapped)

  RISC指令系统的CPU(如ARM、PowerPC等)通常只实现一个物理地址空间,外设I/O端口成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。

 但是,这两者在硬件实现上的差异对于软件来说是完全透明的,驱动程序开发人员可以将内存映射方式的I/O端口和外设内存统一看作是"I/O内存"资源。

驱动程序并不能直接通过物理地址访问I/O内存资源,而必须将它们映射到核心虚地址空间内(通过页表),然后才能根据映射所得到的核心虚地址范围,通过访内指令访问这些I/O内存资源。Linux在io.h头文件中声明了函数ioremap(),用来将I/O内存资源的物理地址映射到核心虚地址空间(3GB-4GB)中,原型如下:

void * ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);

  iounmap函数用于取消ioremap()所做的映射,原型如下:

void iounmap(void * addr);

  这两个函数都是实现在mm/ioremap.c文件中。

ioremap中首先做了一些检查,其中一项检查是要处理的物理地址是不是 RAM ,因为 ioremap 只处理 soc 的 io memory ,不处理 RAM

linux 的4级内存页表。
4级即: PGD -> PUD -> PMD -> PTE

http://larmbr.me/2014/01/19/the-evolution-of-4-level-page-talbe-in-linux/

那什么叫边际效应呢? 我查了查 这个答案比较靠谱
(个人理解就是副作用):读取某个地址时可能导致这个地址的内容发生变化,比如很多中断寄存器的值一经读取,便自动清零

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值