zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

一文搞懂CPU如何控制I/O设备

2023-02-25 18:27:01 时间

1 接口和设备:经典适配器模式

输入输出设备不只是一个设备。大部分输入输出设备,都有:

  • 它的接口(Interface)
  • 实际的I/O设备(Actual I/O Device)

硬件设备并非直接接入到总线上和CPU通信,而是通过接口,用接口连接到总线,再通过总线和CPU通信。

SATA硬盘,绿色电路板和黄色齿状部分就是接口电路,黄色齿状的就是和主板对接的接口,绿色的电路板就是控制电路。

并行接口(Parallel Interface)、串行接口(Serial Interface)、USB接口都是计算机主板上内置的各接口。实际硬件设备,如使用并口的打印机、使用串口的鼠标或使用USB接口的U盘,都要插入这些接口,才能和CPU工作及通信。

接口本就是块电路板。CPU不和实际硬件设备打交道,而是和这接口电路板交互。设备里有三类寄存器,都在这设备的接口电路,而不在实际设备:

  • 状态寄存器(Status Register)
  • 命令寄存器(Command Register)
  • 数据寄存器(Data Register)

除了内置在主板上的接口之外,有些接口可集成在设备上。90年代用都是IDE硬盘,集成设备电路(Integrated Device Electronics)。设备的接口电路直接在设备上,而不在主板。要通过一个线缆,把集成了接口的设备连接到主板上去。

PC的设备管理器:

把接口和实际设备分离,来自于计算机走向开放架构(Open Architecture)的时代。

  • 当对计算机升级,不会扔旧计算机,直接买全新计算机,而是可单独升级硬盘。把老硬盘从接口上拿走,换个新的上去
  • 各种输入输出设备的制造商,也可根据接口的控制协议,来设计和制造硬盘、鼠标、键盘、打印机乃至其他种种外设

OOP里的面向接口编程的接口,就是Interface。Adaptor设计模式更是常见用来解决不同外部应用和系统“适配”问题的方案。

设备管理器里有各种Devices(设备)、Controllers(控制器)、Adaptors(适配器)。都是对于输入输出设备不同角度的描述:

  • Devices,看重实际的I/O设备本身
  • Controllers,看重输入输出设备接口里面的控制电路
  • Adaptors,看重接口作为一个适配器后面可以插上不同的实际设备

2 CPU如何控制I/O设备

无论内置在主板上的接口or集成在设备上的接口,除三类寄存器,还有对应控制电路。正是控制电路,CPU才能通过向这个接口电路板传输信号,控制实际硬件。

硬件设备的这些寄存器有啥用?

打印机案例

  • 数据寄存器(Data Register) CPU向I/O设备写入需要传输的数据,比如要打印“Time”,就要先发送一个“T”到对应I/O设备。
  • 命令寄存器(Command Register) CPU发送一个命令,告诉打印机,要进行打印。这时,打印机里的控制电路会:
  • 设置状态寄存器里面的状态,把状态设置成not-ready
  • 实际操作打印机进行打印
  • 状态寄存器(Status Register) 告诉CPU,现在设备已经在工作了,这时,CPU你再发送数据或者命令过来,都是没有用的。直到前面的动作已经完成,状态寄存器重新变成了ready状态,我们的CPU才能发送下一个字符和命令。

打印机里通常不只有数据寄存器,还有数据缓冲区。CPU也不是真的一个字符一个字符交给打印机去打印,而是一次性把整个文档传输到打印机的内存或数据缓冲区里一起打印。

3 信号和地址:发挥总线的价值

CPU往总线发啥命令,才能和I/O接口上的设备通信?

CPU和I/O设备的通信也是通过CPU支持的机器指令执行的。

MIPS的机器指令的分类并没有一种专门的和I/O设备通信的指令类型。那MIPS CPU是通过什么样的指令来和I/O设备通信? 和访问主内存一样,使用“内存地址”。为让CPU尽可能简单,计算机把I/O设备的各寄存器及I/O设备内部的内存地址,都映射到主内存地址空间。 主内存地址空间里,会给不同I/O设备预留一段段内存地址。CPU想要和这些I/O设备通信,就往这些地址发数据:

  • 这些地址信息,就是地址线发送的
  • 对应的数据信息通过数据线发送

I/O设备会监控地址线,并在CPU往自己地址发数据时,把对应数据线里传输过来的数据,接入到对应的设备里的寄存器和内存。 CPU无论是向I/O设备发命令、查询状态还是传输数据,都可这样。这种方式叫内存映射IO(Memory-Mapped I/O,简称MMIO)。

MMIO是唯一的一种CPU和设备通信的方式吗? No!MIPS CPU很简单,所以这里只有MMIO。而有2000多个指令的Intel X86计算机,自然可以设计专门的和I/O设备通信的指令:in、out 指令。

Intel CPU虽支持MMIO,不过还可以通过特定指令支持:

  • 端口映射I/O(Port-Mapped I/O,简称PMIO)
  • 或独立输入输出(Isolated I/O)

PMIO的通信方式和MMIO差不多,区别在于PMIO里访问的设备地址,不再是在内存地址空间里,而是一个专门的端口(Port)。

该端口并非一个硬件上的插口,而是和CPU通信的一个抽象概念

PMIO、MMIO,CPU都会传送一条二进制数据,给到I/O设备的对应地址。 设备自己本身的接口电路,再去解码这个数据。解码后的数据变成设备支持的一条指令,再通过控制电路去操作实际的硬件设备。 对CPU,它并不需关心设备本身能够支持哪些操作。它要做的,只是在总线上传输一条条数据就好了。

这就像Command设计模式,在总线上传输的,是一个个数据对象,然后各接受这些对象的设备,再根据对象内容,进行实际解码和命令执行。

设备管理器里显卡设备的资源信息:

设备管理器里面的资源(Resource)信息。里面既有Memory Range,这个就是设备对应映射到的内存地址,也就是我们上面所说的MMIO的访问方式。还有I/O Range,即PMIO,通过端口来访问I/O设备的地址。 IRQ,会来自于这个设备的中断信号。

4 总结

CPU并非发送一个特定操作指令来操作不同I/O设备。若那样,新I/O设备发明,就要去扩展CPU指令集。

CPU和I/O设备之间的通信是这么解决:

首先,在I/O设备这一侧,我们把I/O设备拆分成,能和CPU通信的接口电路,以及实际的I/O设备本身。接口电路里面有对应的状态寄存器、命令寄存器、数据寄存器、数据缓冲区和设备内存等等。接口电路通过总线和CPU通信,接收来自CPU的指令和数据。而接口电路中的控制电路,再解码接收到的指令,实际去操作对应的硬件设备。

CPU侧,对CPU,它看到的并非一个个特定设备,而是一个个内存地址或端口地址。CPU只是向这些地址传输数据或读取数据。所需要的指令和操作内存地址的指令无本质差别。通过软件层对传输的命令数据的定义实际操作对应的I/O硬件。