linux内存操作--ioremap和mmap学习笔记
最近做一些相关的视频输出,对于保留framebuffer内存使用情况不是很清楚,现在找了一些资料整理出,准备使用。if (希望看到使用) goto 用法;
对于一个系统来讲,会有非常多的外设,那么这些外设的管理都是通过CPU完毕。那么CPU在这个过程中是怎样找到外设的呢?
虽然在一个系统中会有诸多的外设,在每一个外设的接口电路中会有多个port。可是假设系统可以每一个port都被赋予一个详细的地址值。那么在系统中就能轻易的找到不论什么一个外设。系统在管理的时候。无论是内存还是外设都须要分配一个内存地址。对于一个32bit的系统来讲,可寻址的范围为2^32=4G的地址空间。
既然说到地址空间,就要明白地址空间的种类:物理地址、总线地址、虚拟地址。
(1)物理地址
CPU地址总线传来的地址,由硬件电路控制其详细含义。
物理地址中非常大一部分是留给内存条中内存的。但也常被映射到其它存储器上(如显存、bios等)。
在程序指令中的虚拟地址经过段映射和页面映射后。就生成了物理地址,这个物理地址被放到CPU的地址线上。
(2)总线地址
总线的地址线或在地址周期上产生的信号。
外设使用的是地址总线,cpu使用的是物理地址。
物理地址和总线地址之间的关系有系统设计决定的。
在X86平台上,物理地址就是总线地址。这是由于它们共享同样的地址空间。在其它平台上,可能须要转换/映射。
(3)虚拟地址
现代操作系统普遍採用虚拟内存管理(virtual memory management)机制,这须要MMU的支持。
MMU一般是CPU的一部分,假设处理器没有MMU,或者有MMU但没有启用,CPU运行单元发出的内存地址将直接传到芯片引脚上,被内存芯片(物理内存)接收。这成为物理地址。假设处理器启用了MMU,CPU运行单元发出的内存地址将被MMU截获,从CPU到MMU的地址称为虚拟地址,而MMU将这个地址翻译成还有一个地址发到CPU芯片的外部地址引脚上。也就是讲虚拟地址映射成物理地址。
linux中,进程的4GB内存分为用户空间和内核空间。
用户空间分布为1~3GB剩下的1GB为内核空间。程序猿仅仅能使用虚拟地址。
系统中每一个进程有各自的私实用户控件(0~3GB),这个空间对系统中的其它进程是不可见的。
编址方式
外设都是通过读写设备上的寄存器来进行工作的,外设寄存器也称为“IOport”,而IOport的编址方式有两种,独立编址和统一编址。
统一编址:外设接口中的IO寄存器(即IOport)与主存单元一样看待,每一个port占用一个存储单元的地址,将主存的一部分划出来用作IO地址空间。
统一编址的原理是将IO的port地址存储器寻址的地址空间范围之内,此方法也成为存储器映像编址。
CPU訪问一个port的操作与訪问内存的操作同样,也使用訪问内存的指令。
独立编址是为port地址单独开辟一部分地址空间,其訪问指令也须要使用单独的指令(不同于内存訪问指令)。
依据CPU体系结构的不同,CPU对IOport的编址方式有两种:
(1)I/O映射方式(I/O-mapped)
典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为"I/O地址空间"或者"I/Oport空间",CPU通过专门的I/O指令(如X86的IN和OUT指令)来訪问这一空间中的地址单元。
(2)内存映射方式(Memory-mapped)
RISC指令系统的CPU(如ARM、PowerPC等)通常仅仅实现一个物理地址空间,外设I/Oport成为内存的一部分。
此时,CPU能够象訪问一个内存单元那样訪问外设I/Oport,而不须要设立专门的外设I/O指令。
可是,这两者在硬件实现上的差异对于软件来说是全然透明的,驱动程序开发者能够将内存映射方式的I/Oport和外设内存统一看作是"I/O内存"资源。
一般来说,在系统执行时,外设的I/O内存资源的物理地址是已知的。由硬件的设计决定。可是CPU通常并没有为这些已知的外设I/O内存资源的物理地址提前定义虚拟地址范围。驱动程序并不能直接通过物理地址訪问I/O内存资源。而必须将它们映射到核心虚地址空间内(通过页表),然后才干依据映射所得到的核心虚地址范围,通过訪内指令訪问这些I/O内存资源。
void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long
flags)
入口: phys_addr:要映射的起始的IO地址。
size:要映射的空间的大小。
flags:要映射的IO空间的和权限有关的标志;
功能: 将一个IO地址空间映射到内核的虚拟地址空间上去。便于訪问;
实现:对要映射的IO地址空间进行推断。低PCI/ISA地址不须要又一次映射。也不同意用户将IO地址空间映射到正在使用的RAM中,最后申请一 个 vm_area_struct结构。调用remap_area_pages填写页表,若填写过程不成功则释放申请的vm_area_struct空
间;
意义:
比方isa设备和pci设备,或者是fb。硬件的跳线或者是物理连接方式决定了硬件上的内存影射到的cpu物理地址。
在内核訪问这些地址必须分配给这段内存以虚拟地址,这正是__ioremap的意义所在 ,须要注意的是,物理内存已经"存在"了,无需alloc page给这段地址了.
为了使软件訪问I/O内存,必须为设备分配虚拟地址.这就是ioremap的工作.这个函数专门用来为I/O内存区域分配虚拟地址(空间).对于直接映射的I/O地址ioremap不做不论什么事情。
有了ioremap(和iounmap),设备就能够訪问不论什么I/O内存空间,不论它是否直接映射到虚拟地址空间.可是,这些地址永远不能直接使用(指物理地址),而要用readb这样的函数。
使用I/O内存首先要申请,然后才干映射,使用I/Oport首先要申请,或者叫请求,对于I/Oport的请求意思是让内核知道你要訪问这个port,这样内核知道了以后它就不会再让别人也訪问这个port了.毕竟这个世界僧多粥少啊.申请I/Oport的函数是request_region,
申请I/O内存的函数是request_mem_region。
request_mem_region函数并没有做实际性的映射工作,仅仅是告诉内核要使用一块内存地址。声明占有。也方便内核管理这些资源。重要的还是ioremap函数,ioremap主要是检查传入地址的合法性,建立页表(包含訪问权限),完毕物理地址到虚拟地址的转换。
用法:
内核中的使用,往往是为某个设备预留一块内存,当使用的时候须要在board中定义这个设备的内存resource。通过
platform_get_resource获得设备的起始地址后。能够对其进行request_mem_region和ioremap等操作,以便应用程序对其进行操作。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
linux内存操作--ioremap和mmap学习笔记的更多相关文章
- linux内存操作--ioremap和mmap
最近在做视频输出相关的东西,对于预留给framebuffer的内存使用不是很清楚,现在找到一些资料整理一下,以备使用.if (想看使用方法) goto 使用方法: 对于一个系统来讲,会有很多的外 ...
- linux 内存映射-ioremap和mmap函数
最近开始学习Linux驱动程序,将内存映射和ioremap,mmap函数相关资料进行了整理 一,内存映射 对于提供了MMU(存储管理器,辅助操作系统进行内存管理,提供虚实地址转换等硬件支持)的处理器 ...
- 《Linux内核分析》第一周学习笔记
<Linux内核分析>第一周学习笔记 计算机是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/c ...
- 《Linux内核分析》第二周学习笔记
<Linux内核分析>第二周学习笔记 操作系统是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...
- 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序(老罗学习笔记3)
简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中.接着,在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)一文中举例子说明了如何在 ...
- 《Linux内核分析》第四周学习笔记
<Linux内核分析>第四周学习笔记 扒开系统调用的三层皮(上) 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.c ...
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...
- linux内核分析第五周学习笔记
linux内核分析第五周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux内核分析第三周学习笔记
linux内核分析第三周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
随机推荐
- HTML5:footer定位(底部+居中)的探讨+div图片居中问题
初学HTML+CSS布局,尝试自己写一个百度首页,可是footer的定位遇到麻烦而且百度没有好的解决方法,在此记录下逐步的过程.记录之,备忘. 初学,解决方法难免出现不妥之处,也请看到这篇文章的前辈指 ...
- SE 2014 年4月21日(二)
实验练习: 如图配置: 两BGP自治系统,要求建立相关BGP邻居关系 1. 建立BGP邻居关系 要求使用BGP对等体组完成(IBGP要求使用loopback接口作为TCP建立的源接口) 2. R3 R ...
- Java与C/C++有什么区别
JDK包含JRE, 1-08: Helloworld: 01-08:classpath配置: 运行其它目录下的class文件: classpath一般不加分号,只找classpath下的文件: 后面加 ...
- 重温delphi之控制台程序:Hello World!
原文:重温delphi之控制台程序:Hello World! 这二天用c#开发ActiveX时,发现不管怎么弄,c#就是没办法生成ocx的纯正activeX控件,而且还要强迫用户安装巨大的.net f ...
- How to debug with IntelliJ IDEA + Grails 2.3.x (转)
问题: 最近访问grails.org,看到grails framework已经发展到2.3.x了,不免想尝尝鲜.下载了最新的grails-2.3.x之后,创建了一个新的grails app. 添加Bo ...
- 基于CentOS 5.4搭建nginx+php+spawn-fcgi+mysql高性能php平台
一.安装准备 1.1平台环境: CentOS 5.4 x86_64 GNU/Linux nginx-0.8.21 php-5.2.9 spawn-fcgi-1.6.3 mysql-5.1.34 .2系 ...
- 使用 DBMS_REPAIR 修复坏块
对于Oracle数据块物理损坏的情形,在我们有备份的情况下可以直接使用备份来恢复.对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等.对于这几种方式我们需要 ...
- adodb.RecordSet的属性和方法
为了更精确地跟踪数据,要用RecordSet组件创建包括数据的游标,游标就是储存在内存中的数据: rs = Server.CreateObject("ADODB.RecordSet" ...
- java Socket的怪异之处
怪异之一: connect(SocketAddress endpoint):这个方法,尝试连接server端,如果连接不上,就抛出IOException异常.如果连接成功了,就继续执行下一步的代码. ...
- Easyui 异步树直接所有展开
初始化异步树直接所有展开代码: $(function(){ $('#tt').tree({ url:'<%=request.getContextPath()%>/treeInit', li ...