接口和设备: 经典的适配器模式
1 2 3 4 5 6 7 8 9 10
| 实际上, 输出输入设备、并不只是一个设备、大部分的输入输出设备、都有两个组成部分. 接口和实际的IO设备. 硬件设备不是直接接入到总线上和CPU通信的、而是通过接口、用接口连接到总线上 再通过总线和CPU通信的. 平时听说的并行接口, 串行接口、 USB接口都是计算机主板上内置的各个接口, 实际的硬件设备 eg. 使用并口的打印机、使用串口的老式鼠标 或者使用USB接口的U盘、都要插入到这些接口上、才能和CPU工作及通信的.
接口本身就是一块电路板、CPU其实不是和实际的硬件设备打交道、而是和这个接口电路板打交道. 常说的设备里有三类寄存器、都在设备的接口电路上、而不是实际的设备上.
三类寄存器: 状态寄存器、命令寄存器和数据寄存器
|
CPU是如何控制IO设备的
1 2 3 4
| 无论是内置在主板上的接口、还是集成在设备上的接口、除了3类寄存器之外、还有对应的控制电路, 正是通过这个控制电路、CPU才能向这个接口电路板传输信号、来控制实际的硬件
设备上的寄存器有什么用呢 ?
|
1 2 3 4 5 6 7 8 9
| 1. 数据寄存器. CPU向IO设备写入需要传输的数据、eg. 要打印`GeekTime`, 会先发送一个G给对应IO设备 2. 命令寄存器. CPU发送一个命令、告诉打印机、要打印. 此时打印机里的控制电路会做两个动作. 1) 设置状态寄存器里的状态为 not-ready 2) 实际操作打印机进行打印 3. 状态寄存器. 告诉CPU、设备已经在工作了、此时再发送数据或者命令都是无效的 直到前边的动作已完成、状态寄存器重新变成ready状态、CPU才发送下一个字符和命令
在实际情况中、打印机通常不止有数据寄存器还有数据缓冲区、CPU也不是真的一个字符一个字符交给打印机处理的 而是一次性将整个文档传输至打印机的内存或者数据缓冲区一起打印的
|
信号和地址: 发挥总线的价值
1 2 3 4 5 6 7 8 9 10 11
| CPU到底要往总线上发送一个什么样的命令、才能和IO接口上的设备通信呢 ?
CPU和IO设备的通信、一样是通过CPU支持的机器指令来执行的. 和访问主内存一样、使用内存地址来和IO设备通信. 为了让已经足够复杂的CPU尽可能简单、 计算机会把IO设备的各个寄存器及IO设备内部的内存地址、都映射到主内存地址空间来、 主内存的地址空间里、会给不同的IO设备预留一段一段的内存地址. CPU想和IO设备通信的时候、 就往这些地址发送数据、这些地址信息就是通过地址总线老来发送的、对应的数据信息就是通过数据总线发送的
而IO设备、会监控地址线、且在CPU往自己的地址发送数据的时候、把对应的数据线里边传输过来的数据、 接入到对应的设备里边的寄存器和内存里. CPU无论是向IO设备发送命令、查询状态还是传输数据都可以 通过这种方式. 称为内存映射IO(Memory-Mapped IO, MMIO)
|
那么、MMIO是不是唯一一种CPU和设备通信的方式呢 ?
1 2 3 4 5 6 7 8 9 10 11
| 不是的. 精简指令集MIPS的CPU特别简单、所以这里只有MMIO. 而有2000多个指令的Intel 而我们有2000多个指令的Intel X86架构的计算机、有专门的和IO设备通信的指令, 即: in 和 out 指令. Intel CPU虽然也支持MMIO、不过还可以通过特定的指令、来支持端口映射IO(Port-Mapped IO, 简称PMIO) 也可以叫独立输入输出(Isolated IO)
其实PMIO的通信方式和MMIO差不多、核心区别在于: PMIO里访问的设备地址、不再是在内存地址空间里、 而是一个专门的端口, 这个端口不是硬件杀昂的插口、而是和CPU通信的一个抽象概念
无论是PMIO还是MMIO、CPU都会传送一条二进制的数据、给到IO设备的对应地址. 设备自己本身的接口电路、 再去解码这个数据、解码之后的数据会变成设备支持的一条指令、再去通过控制电路操作实际的硬件设备 对CPU来说、它不关心设备本身可以支持哪些操作、只是在总线上传输一条条数据就好了.
|