接口和设备
输入输出设备,并不只是一个设备。大部分的输入输出设备,都有两个组成部分。第一个是它的接口(Interface),第二个才是实际的 I/O 设备(Actual I/O Device)。硬件设备并不是直接接入到总线上和 CPU 通信的,而是通过接口,用接口连接到总线上,再通过总线和 CPU 通信。
接口本身就是一块电路板。CPU 其实不是和实际的硬件设备打交道,而是和这个接口电路板打交道。我们平时说的,设备里面三类寄存器,即状态寄存器(Status Register)、 命令寄存器(Command Register)以及数据寄存器(Data Register),其实都在这个设备的接口电路上,而不在实际的设备上。
CPU 控制 I/O 设备
无论是内置在主板上的接口,还是集成在设备上的接口,除了三类寄存器之外,还有对应的控制电路。正是通过这个控制电路,CPU 才能通过向这个接口电路板传输信号,来控制实际的硬件。
数据寄存器(Data Register):保存设备的输出或计算机的输入。
命令寄存器(Command Register):计算机控制设备做出操作,要做的操作存储在此。
状态寄存器(Status Register):设备完成操作之后,告诉计算机当前的状态。
扩展阅读:I/O 控制方式
信号与地址
CPU 和 I/O 设备的通信,一样是通过 CPU 支持的机器指令来执行的。
为了让已经足够复杂的 CPU 尽可能简单,计算机会把 I/O 设备的各个寄存器,以及 I/O 设备内部的内存地址,都映射到主内存地址空间里来。主内存的地址空间里,会给不同的 I/O 设备预留一段一段的内存地址。CPU 想要和这些 I/O 设备通信的时候,就往这些地址发送数据。这些地址信息,就是通过址线来发送的,对应的数据信息,自然就是通过数据线来发送的了。
I/O 设备就会监控地址线,并且在 CPU 往自己地址发送数据的时候,把对应的数据线里面传输过来的数据,接入到对应的设备里面的寄存器和内存里面来。CPU 无论是向 I/O 设备发送命令、查询状态还是传输数据,都可以通过这样的方式。这种方式叫作内存映射IO(Memory-Mapped I/O,简称 MMIO)。
除此之外还有端口映射 I/O(Port-Mapped I/O,简称 PMIO)或者也可以叫独立输入输出(Isolated I/O)。
无论是 PMIO 还是 MMIO,CPU 都会传送一条二进制的数据,给到 I/O 设备的对应地址。设备自己本身的接口电路,再去解码这个数据。解码之后的数据,就会变成设备支持的一条指令,再去通过控制电路去操作实际的硬件设备。对于 CPU 来说,它并不需要关心设备本身能够支持哪些操作。它要做的,只是在总线上传输一条条数据。
小结
在计算机系统里面,CPU 和 I/O 设备之间的通信,大致为如下过程。
首先,在 I/O 设备这一侧,我们把 I/O 设备拆分成,能和 CPU 通信的接口电路,以及实际的 I/O 设备本身。接口电路里面有对应的状态寄存器、命令寄存器、数据寄存器、数据缓冲区和设备内存等等。接口电路通过总线和 CPU 通信,接收来自 CPU 的指令和数据。而接口电路中的控制电路,再解码接收到的指令,实际去操作对应的硬件设备。
而在 CPU 这一侧,对 CPU 来说,它看到的并不是一个个特定的设备,而是一个个内存地址或者端口地址。CPU 只是向这些地址传输数据或者读取数据。所需要的指令和操作内存地址的指令其实没有什么本质差别。通过软件层面对于传输的命令数据的定义,而不是提供特殊的新的指令,来实际操作对应的 I/O 硬件。
