第二个方法是 PDP-11 引入的,
什么是 PDP-11?
”
它将所有控制寄存器映射到内存空间中,如下图所示
内存映射的 I/O
是在 CPU 与其连接的外围设备之间交换数据和指令的一种方式,这种方式是处理器和 IO 设备共享同一内存位置
的内存,即处理器和 IO 设备使用内存地址进行映射。
在大多数系统中,分配给控制寄存器的地址位于或者靠近地址的顶部附近。
下面是采用的一种混合方式
这种方式具有与内存映射 I/O 的数据缓冲区,而控制寄存器则具有单独的 I/O 端口。x86 采用这一体系结构。在 IBM PC 兼容机中,除了 0 到 64K - 1 的 I/O 端口之外,640 K 到 1M - 1 的内存地址保留给设备的数据缓冲区。
这些方案是如何工作的呢?当 CPU 想要读入一个字的时候,无论是从内存中读入还是从 I/O 端口读入,它都要将需要的地址放到总线地址线上,然后在总线的一条控制线上调用一个 READ
信号。还有第二条信号线来表明需要的是 I/O 空间还是内存空间。如果是内存空间,内存将响应请求。如果是 I/O 空间,那么 I/O 设备将响应请求。如果只有内存空间,那么每个内存模块和每个 I/O 设备都会将地址线和它所服务的地址范围进行比较。如果地址落在这一范围之内,它就会响应请求。绝对不会出现地址既分配给内存又分配给 I/O 设备,所以不会存在歧义和冲突。
内存映射 I/O 的优点和缺点
这两种寻址控制器的方案具有不同的优缺点。先来看一下内存映射 I/O 的优点。
- 第一,如果需要特殊的 I/O 指令读写设备控制寄存器,那么访问这些寄存器需要使用汇编代码,因为在 C 或 C++ 中不存在执行
IN
和OUT
指令的方法。调用这样的过程增加了 I/O 的开销。在内存映射中,控制寄存器只是内存中的变量,在 C 语言中可以和其他变量一样进行寻址。 - 第二,对于内存映射 I/O ,不需要特殊的保护机制就能够阻止用户进程执行 I/O 操作。操作系统需要保证的是禁止把控制寄存器的地址空间放在用户的虚拟地址中就可以了。
- 第三,对于内存映射 I/O,可以引用内存的每一条指令也可以引用控制寄存器,便于引用。
在计算机设计中,几乎所有的事情都要权衡。内存映射 I/O 也是一样,它也有自己的缺点。首先,大部分计算机现在都会有一些对于内存字的缓存。缓存一个设备控制寄存器的代价是很大的。为了避免这种内存映射 I/O 的情况,硬件必须有选择性的禁用缓存,例如,在每个页面上禁用缓存,这个功能为硬件和操作系统增加了额外的复杂性,因此必须选择性的进行管理。
第二点,如果仅仅只有一个地址空间,那么所有的内存模块(memory modules)
和所有的 I/O 设备都必须检查所有的内存引用来推断出谁来进行响应。
什么是内存模块?在计算中,存储器模块是其上安装有存储器集成电路的印刷电路板。
”如果计算机是一种单总线体系结构的话,如下图所示
让每个内存模块和 I/O 设备查看每个地址是简单易行的。
然而,现代个人计算机的趋势是专用的高速内存总线,如下图所示
装备这一总线是为了优化内存访问速度,x86 系统还可以有多种总线(内存、PCIe、SCSI 和 USB)。如下图所示
在内存映射机器上使用单独的内存总线的麻烦之处在于,I/O 设备无法通过内存总线查看内存地址,因此它们无法对其进行响应。此外,必须采取特殊的措施使内存映射 I/O 工作在具有多总线的系统上。一种可能的方法是首先将全部内存引用发送到内存,如果内存响应失败,CPU 再尝试其他总线。
第二种设计是在内存总线上放一个探查设备
,放过所有潜在指向所关注的 I/O 设备的地址。此处的问题是,I/O 设备可能无法以内存所能达到的速度处理请求。
第三种可能的设计是在内存控制器中对地址进行过滤,这种设计与上图所描述的设计相匹配。这种情况下,内存控制器芯片中包含在引导时预装载的范围寄存器。这一设计的缺点是需要在引导时判定哪些内存地址而不是真正的内存地址。因而,每一设计都有支持它和反对它的论据,所以折中和权衡是不可避免的.
直接内存访问
无论一个 CPU 是否具有内存映射 I/O,它都需要寻址设备控制器以便与它们交换数据。CPU 可以从 I/O 控制器每次请求一个字节的数据,但是这么做会浪费 CPU 时间,所以经常会用到一种称为直接内存访问(Direct Memory Access)
的方案。为了简化,我们假设 CPU 通过单一的系统总线访问所有的设备和内存,该总线连接 CPU 、内存和 I/O 设备,如下图所示
现代操作系统实际更为复杂,但是原理是相同的。如果硬件有DMA 控制器
,那么操作系统只能使用 DMA。有时这个控制器会集成到磁盘控制器和其他控制器中,但这种设计需要在每个设备上都装有一个分离的 DMA 控制器。单个的 DMA 控制器可用于向多个设备传输,这种传输往往同时进行。
不管 DMA 控制器的物理地址在哪,它都能够独立于 CPU 从而访问系统总线,如上图所示。它包含几个可由 CPU 读写的寄存器,其中包括一个内存地址寄存器,字节计数寄存器和一个或多个控制寄存器。控制寄存器指定要使用的 I/O 端口、传送方向(从 I/O 设备读或写到 I/O 设备)、传送单位(每次一个字节或者每次一个字)以及在一次突发传送中要传送的字节数。
为了解释 DMA 的工作原理,我们首先看一下不使用 DMA 该如何进行磁盘读取。
- 首先,控制器从
磁盘驱动器
串行地、一位一位的读一个块(一个或多个扇区),直到将整块信息放入控制器的内部缓冲区。 - 读取
校验和
以保证没有发生读错误。然后控制器会产生一个中断,当操作系统开始运行时,它会重复的从控制器的缓冲区中一次一个字节或者一个字地读取该块的信息,并将其存入内存中。