操作系统控制计算机的所有输入输出(IO)设备, 向它们发送信号, 处理中断和错误.
IO设备通信机制
IO设备通常由存储部件和设备控制器(device controller)组成. 设备控制器又称为适配器(adapter), 通常在主板芯片组中或者插入PCI扩展槽中.
每个控制器都有几个控制寄存器用来与CPU通信, 操作系统可以通过读写控制寄存器获得设备状态或操作设备.
除了控制寄存器外,很多设备还拥有内存中的数据缓冲区.
每个IO设备都拥有唯一的IO端口号(IO port), 所有IO端口形成IO空间.用户程序无权访问IO端口, 只有操作系统可以使用IO指令访问端口:
IN REG,PORT
OUT PORT,REG
另外一种被称为内存映射IO的方法中, 控制寄存器被映射到内存中, 程序通过访问内存的形式访问IO设备.
所谓映射是指对内存映像的修改将写入控制寄存器, 控制寄存器的变化也将被写入内存.
因为IO设备被映射到内存中, 只需要将IO设备在内存中的映像放入内核空间中就可以避免用户程序非法访问IO设备.
IO设备在内存中的映像可以通过常规方式访问, 不再需要特殊的IO指令.
但是若IO设备的内存映像被高速缓存,CPU对IO设备的访问将变成访问高速缓存中的数据.CPU发送的信号无法通过映射机制发送到IO设备, CPU读取的IO设备状态和缓冲区始终是被缓存时的数据.
简单地说, 若IO设备的内存映像被高速缓存CPU将无法与IO设备通信.所以, 必须将设备的内存映像设置为不可缓存的状态.
现代计算机为了提高内存访问的速度, 通常使用了专用的内存总线.内存映射机制要求IO设备也可以访问内存, 因此需要在系统总线中增加访问内存的端口:
本节介绍了内存映射IO等CPU与IO设备通信的机制.CPU在IO过程中的具体行为, 需要操作系统软件进行控制.
程序驱动IO
实现IO最简单的方法就是让CPU来完成所有的操作, 这种方法被称为程序驱动IO.
我们以一个拥有打印机守护进程和内存映射机制的系统为例.
一个用户程序想要进行打印操作, 它会发出一个系统调用使得打印机守护进程建立一个新的打印机任务.
操作系统(通常)将要打印的字符串复制到内核空间中, 修改打印机的内存映像激活打印机输出缓冲区中的字符.
中断驱动IO
当一个IO设备完成工作时,它将通过IO总线上的中断线向中断控制器发出一个中断.
中断控制器通过系统总线上的地址线向CPU发送中断信号, 中断信号指向内存中一个称为中断向量数据区.
中断信号使得CPU中断当前的操作保存现场, 然后处理中断事件.
IO设备通常是低速设备,假设一台一次只能打印一个字符的打印机, 其打印一个字符需要10ms.
若采用程序驱动IO, CPU发出打印一个字符指令后必须等待10ms的时间打印机才能再次就绪打印下一个字符.
这显然是非常浪费CPU资源的, 中断驱动机制允许CPU发出打印一个字符的指令后切换到其它任务.
当打印机再次就绪时, CPU会收到一个中断信号.CPU收到中断信号发出打印下一个字符的指令, 然后切换到其它任务继续执行.
在中断驱动机制下, CPU不需要等待慢速设备, 主要因为切换进程产生额外开销.
直接内存访问
直接内存访问(Direct Memory Access,DMA)机制, 降低了CPU中断响应的压力提高了CPU利用率.
DMA需要专职的DMA控制器来实现, DMA控制器可以与CPU通信并单独访问IO设备.
DMA控制器中包含地址,计数和控制寄存器, CPU可以通过控制寄存器为其编程.
DMA机制与程序驱动IO类似, 只不过程序驱动IO中CPU的任务交给了DMA控制器来完成.
依旧以一次只能打印一个字符的打印机为例, CPU将任务发送给DMA控制器.
DMA控制器读取缓冲区, 并将要打印的字符发送给打印机,当打印机再次就绪后发送下一个字符.
当缓冲区打印完毕, DMA控制器向CPU发出中断信号.使用DMA机制使得CPU从每个字符处理一次中断变为打印一个缓冲区处理一个中断, 极大减轻了CPU的负担.
设计复杂的DMA的控制器采用了多路传送和轮转机制,使得DMA在IO设备工作时处理其它任务.