内存映射IO(MMIO)
端口I/O
介绍:
一种I/O编址方式是端口映射I/O(port-mapped I/O), CPU使用专门的I/O指令对设备进行访问, 并把设备的地址称作端口号. 在执行其中的一条指令时,CPU使用地址总线选择所请求的I/O端口,使用数据总线在CPU寄存器和端口之间传送数据。
目的:
系统设计者的主要目的是提供对I/O编程的统一方法,但又不牺牲性能。为了达到这个目的,每个设备的I/O 端口都被组织成一组专用寄存器。CPU把要发给设备的命令写入控制寄存器(control register),并从状态寄存器(status register)中读出表示设备内部状态的值。CPU还可以通过读取输入寄存器(input register)的内容从设备取得数据,也可以通过向输出寄存器(output register)中写入字节而把数据输出到设备。
举例:
以x86为例,x86提供了in和out指令用于访问设备,其中in
指令用于将设备寄存器中的数据传输到CPU寄存器中, out
指令用于将CPU寄存器中的数据传送到设备寄存器中. 一个例子是使用out
指令给串口发送命令字:
movl $0x41, %al
movl $0x3f8, %edx
outb %al, (%dx)
上述代码把数据0x41传送到0x3f8号端口所对应的设备寄存器中. CPU执行上述代码后, 会将0x41这个数据传送到串口的一个寄存器中, 串口接收之后, 发现是要输出一个字符A
; 但对CPU来说, 它并不关心设备会怎么处理0x41这个数据, 只会老老实实地把0x41传送到0x3f8号端口. 事实上, 设备的API及其行为都会在相应的文档里面有清晰的定义, 在PA中我们无需了解这些细节, 只需要知道, 驱动开发者可以通过RTFM, 来编写相应程序来访问设备即可.
内存映射I/O
介绍:
MMIO(Memory mapping I/O)即内存映射I/O,它是PCI规范的一部分,I/O设备被放置在内存空间而不是I/O空间。从处理器的角度看,内存映射I/O后系统设备访问起来和内存一样。这样访问AGP/PCI-E显卡上的帧缓存,BIOS,PCI设备就可以使用读写内存一样的汇编指令完成,简化了程序设计的难度和接口的复杂性。I/O作为CPU和外设交流的一个渠道,主要分为两种,一种是Port I/O,一种是MMIO(Memory mapping I/O)。(来自百度百科)
目的:
早期的PC中,所有的IO设备(除了存储设备之外的设备)的内部存储或者寄存器都只能通过IO地址空间进行访问(Intel干的好事)。但是这种方式局限性很大,而且效率低,于是乎,软件开发者和硬件厂商都不能忍了……然后一种新的东西就出来了——MMIO。MMIO,即Memory Mapped IO,也就是说把这些IO设备中的内部存储和寄存器都映射到统一的存储地址空间(Memory Address Space)中。但是,为了兼容一些之前开发的软件,PCIe仍然支持IO地址空间,只是建议在新开发的软件中采用MMIO。
内存映射I/O这种编址方式非常巧妙, 它是通过不同的物理内存地址给设备编址的. 这种编址方式将一部分物理内存的访问"重定向"到I/O地址空间中, CPU尝试访问这部分物理内存的时候, 实际上最终是访问了相应的I/O设备, CPU却浑然不知.
这样以后, CPU就可以通过普通的访存指令来访问设备. 这也是内存映射I/O得天独厚的好处: 物理内存的地址空间和CPU的位宽都会不断增长, 内存映射I/O从来不需要担心I/O地址空间耗尽的问题.
从原理上来说, 内存映射I/O唯一的缺点就是, CPU无法通过正常渠道直接访问那些被映射到I/O地址空间的物理内存了. 但随着计算机的发展, 内存映射I/O的唯一缺点已经越来越不明显了: 现代计算机都已经是64位计算机, 物理地址线都有48根, 这意味着物理地址空间有256TB这么大, 从里面划出3MB的地址空间给显存, 根本就是不痛不痒.
对x86来说, 内存映射I/O的一个例子是NEMU中的物理地址区间[0xa1000000, 0xa1800000)
. 这段物理地址区间被映射到VGA内部的显存, 读写这段物理地址区间就相当于对读写VGA显存的数据. 例如:
memset((void *)0xa1000000, 0, SCR_SIZE);
会将显存中一个屏幕大小的数据清零, 即往整个屏幕写入黑色像素, 作用相当于清屏. 可以看到, 内存映射I/O的编程模型和普通的编程完全一样: 程序员可以直接把I/O设备当做内存来访问. 这一特性也是深受驱动开发者的喜爱.
参考文献:
内存映射IO (MMIO) 简介 - 知乎 (zhihu.com)
PCIe扫盲——Memory & IO 地址空间 - 简书 (jianshu.com)
最新文章
- EditText中imeOptions属性使用及设置无效解决
- 常用CSS优化总结——网络性能与语法性能建议
- 【转】WordPress转PHPCMS策略-数据库完美转换
- ssential Diagram for Windows FormsC#/winForm类似visio的拓扑图节点连线控件免费下载
- Cubieboard2裸机开发之(三)C语言操作LED
- [转载]如何在Ubuntu上安装LAMP服务器系统
- 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
- mysql 5.7压缩包安装笔记
- 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0” 提供程序解决办法
- 高效率使用google
- 用Nodejs+Express搭建web,nodejs路由和Ajax传数据并返回状态,nodejs+mysql通过ajax获取数据并写入数据库
- MyBatis3系列__02接口式编程
- es6 ...克隆与函数深度克隆
- HDFS格式化namenode后启动集群datanode不启动
- jmeter正则表达式提取器多模块相互调用
- website for .Net Core
- SpringMVC 参数中接收数组、List写法
- time out 超时
- Mysql 日期类型 date、datetime、timestamp.
- [转]OData and Authentication – Part 6 – Custom Basic Authentication
热门文章
- 快速新建并配置一个eslint+prettier+husky+commitlint+vue3+vite+ts+pnpm的项目
- 论文解读(GSAT)《Interpretable and Generalizable Graph Learning via Stochastic Attention Mechanism》
- 金瓯无缺江河一统|Win10系统基于Docker和Python3搭建并维护统一认证系统OpenLdap
- 出票系统:根据淡旺季的月份和年龄,打印票价[课后练习] 出票系统:根据淡旺季的月份和年龄,打印票价[课后练习] 4 10旺季: 4 10旺季: 成人(18-60) : 60 成人(18-60):60 儿童(<;18) :半价 儿童(<;18):半价 老人(>;60) :1/3 老人(>;60):1/3 淡季: 淡季: 成人: 40 成人:40 其他: 20 其他:20
- Java多线程超级详解(只看这篇就够了)
- vue自定义switch开关,使用less支持换肤
- CF383C Propagating tree (线段树,欧拉序)
- C++ 特殊矩阵的压缩存储算法
- 超实用在线工具!能将文字加密为Emoji表情
- javaweb-thymeleaf,加载jar包---视图基础