下面我们介绍一下 I/O 硬件的组成。
通常 I/O 设备呢是由机械部分和电子部分组成的
所谓机械部分实际上就是设备本身,它是硬件装置
而电子部分呢是我们熟悉的设备控制器或者是适配器
电子部分主要的工作呢是地址的译码
按照主机与设备之间约定的格式和
过程接受计算机发来的数据或者是控制信号
或者是像主机发送数据和状态的信号 另外呢
电子部分还负责将计算机发来的数字信号转换成机械部分
能识别的模拟信号,或者是反过来
在电子部分还有一项重要的工作就是提供相应的缓冲区
那么在这个缓冲区当中可以进行相应的数据加工
那么提供一些性能和增强功能的这个机制
下面我们来看一下控制器的作用 操作系统将命令
写入控制器的接口寄存器或者是接口缓冲区当中 用来实现输入输出的过程。
同时,操作系统 还会从控制寄存器当中去读取设备的状态或者是结果信息
对控制器而言,当它接受到了一条命令之后 它可以独立于
CPU 完成对设备的控制操作 这个时候
CPU 去可以执行其他的运算过程
当这条命令完成之后,控制器会产生一个中断 CPU
响应中断,然后进入操作系统去做后续的工作
比如说,操作系统会去读控制寄存器当中的信息,获得这次操作的
结果和状态信息 控制器与设备之间的接口通常是一个低级接口
因此控制器的任务呢就是要把串行的位流转换成
字节块并进行必要的错误修正。
具体来说呢 就是首先,控制器按位进行相应的组装
并且存入控制器内部的缓冲区当中,形成以字节为单位的块
再对块相应的数据进行检验
并证明没有错误之后再把相应的内容复制到内存中
那么电子部分或者是
设备控制器,其中一个很重要的工作之一呢是进行端口的地址译码 我们来看一下
I/O 端口的概念。
I/O 端口地址呢实际上是
接口电路当中每个寄存器所具有的唯一的一个地址,是一个整数 所有的
I/O 端口地址呢实际上是形成了一个 I/O
端口的一个空间,那么这个空间呢是受到保护的 I/O
的指令形式实际上是和 I/O 的端口
地址是密切相关的,通常我们提供了两种形式的这种 I/O
端口地址 第一种呢叫做内存映像编址,第二种叫做
I/O 独立编址 而内存映像编址呢,实际上我们也称之为内存映像的
I/O 模式 而 I/O 独立编址呢实际上是专门有相应的 I/O 专用指令。
这是一个示意图 左边我们可以看到,最左边的是一个内存
还有一个是 I/O 端口空间。
中间这个呢实际上就是一块内存 这个内存呢实际上是有一部分用作
I/O 的端口 而在右边这种情况呢是一个混合的。
在内存里头 也有一部分空间用于 I/O 端口,而且还有一部分是
I/O 的独立端口 因此我们可以这里看一下,那么在这种混合方式当中,内存的映射
I/O 的 数据缓冲区呢在内存里有一块空间,同时还有一个独立的
I/O 的端口的控制寄存器空间 所以这是三种不同的形式
下面我们介绍一下 I/O 独立编址 所谓
I/O 独立编址指的是分配给系统当中 所有
I/O 端口的地址空间是完全独立的
是与内存的地址空间没有任何关系的 在这里的呢会使用专门的
I/O 指令对这个端口进行相应的操作 它的优点是,各种各样的外部设备
它的端口不占据内存的地址空间 在编程的时候,由于使用专用的指令
可以很容易区分哪些操作是对 内存的操作,哪些操作是对
I/O 端口的操作 但是它的缺点呢是由于提供给
I/O 端口操作的种类很少,操作呢不够灵活
我们简单地举个例子,在 8086/8088
当中呢分配给 I/O 端口的地址空间呢一共是 64K 只能用 in 和 out
这样的指令对它进行读写操作 这里给出了一个
I/O 端口地址的这个范围,以及
不同的,针对不同设备的分配的地址的范围 下面我们来介绍一下内存映像编址
内存映像编址指的是分配给系统当中所有 I/O
端口的地址空间与内存的地址空间是统一进行编址的 也就是说把
I/O 的端口看作是 一个存储单元。
对 I/O 的读写操作 等同于对内存的操作。
它的优点是 凡是可以对内存操作的指令,都可以去对
I/O 端口 进行操作,不需要专门设计相应的
I/O 指令 那么 I/O 端口的空间呢也可以有比较大的地址空间
它的缺点是它占用了一部分的内存空间 下面我们来讨论一下内存映射
I/O 的优缺点 它的优点是,不需要特殊的
保护机制来阻止用户进程进行相应的 I/O 操作
操作系统所需要做的就是要避免 把包含了控制寄存器的那部分
地址空间放入到用户的虚拟地址空间当中 采用内存映射
I/O 的另外一个优点呢,是可以引用
内存的每一条指令都可以适用于引用控制寄存器 比如说,如果指令
TEST 可以测试一个内存字是否为
0 那么我们也可以拿它来测试某一个控制寄存器是否为
0 因为每个控制寄存器它的端口地址是在内存的某一个位置
内存映射 I/O 的缺点是,不能够
对一个控制寄存器它的内容进行高速缓存 我们来举一个例子
这段代码呢实际上是对端口 4 进行相应的检测
检测的端口是不是为 0,如果这个 端口是 0
说明这个端口准备好了可以进行相应的 I/O 操作了 如果不为 0
就要持续进行检测 但是如果我们把设备控制寄存器进行了
高速缓存,那么第一次引用这个端口 4 的时候就把它 放入了高速缓存。
以后再对它的引用都是从 高速缓存当中取值,而不会再去对设备进行相应的检测
之后如果设备变成就绪的时候呢
软件已经没有办法发现到这一点,因此这个循环就会 永远进行下去了。
为了避免这一情形,硬件 必须针对每个页面
具备了一个选择性禁用高速缓存的能力 我们在前面讲到虚存的
列表项的时候,我们就看到有这么一个叫禁止缓存位
那么这一位就是操作系统可以通过它来管理 选择性的高速缓存。
当然,有了这样一个要求之后 那么这个特点就为
硬件和操作系统增添了额外的复杂性 所以呢我们把它称之为内存映射
I/O 的一个缺点,也就是 对设备控制寄存器我们不能够进行高速缓存