王优秀|A 字母时,操作系统期间发生了什么...,键盘敲入

前言
键盘可以说是我们最常使用的输入硬件设备了 , 但身为程序员的你 , 你知道「键盘敲入A字母时 , 操作系统期间发生了什么吗」?
那要想知道这个发生的过程 , 我们得先了解了解「操作系统是如何管理多种多样的的输入输出设备」的 , 等了解完这个后 , 我们再来看看这个问题 , 你就会发现问题已经被迎刃而解了 。
王优秀|A 字母时,操作系统期间发生了什么...,键盘敲入
文章图片
正文
设备控制器
我们的电脑设备可以接非常多的输入输出设备 , 比如键盘、鼠标、显示器、网卡、硬盘、打印机、音响等等 , 每个设备的用法和功能都不同 , 那操作系统是如何把这些输入输出设备统一管理的呢?
为了屏蔽设备之间的差异 , 每个设备都有一个叫设备控制器(DeviceControl)的组件 , 比如硬盘有硬盘控制器、显示器有视频控制器等 。
王优秀|A 字母时,操作系统期间发生了什么...,键盘敲入
文章图片
因为这些控制器都很清楚的知道对应设备的用法和功能 , 所以CPU是通过设备控制器来和设备打交道的 。
设备控制器里有芯片 , 它可执行自己的逻辑 , 也有自己的寄存器 , 用来与CPU进行通信 , 比如:
通过写入这些寄存器 , 操作系统可以命令设备发送数据、接收数据、开启或关闭 , 或者执行某些其他操作 。
通过读取这些寄存器 , 操作系统可以了解设备的状态 , 是否准备好接收一个新的命令等 。
实际上 , 控制器是有三类寄存器 , 它们分别是状态寄存器(StatusRegister)、命令寄存器(CommandRegister)以及数据寄存器(DataRegister) , 如下图:
王优秀|A 字母时,操作系统期间发生了什么...,键盘敲入
文章图片
这三个寄存器的作用:
数据寄存器 , CPU向I/O设备写入需要传输的数据 , 比如要打印的内容是「Hello」 , CPU就要先发送一个H字符给到对应的I/O设备 。
命令寄存器 , CPU发送一个命令 , 告诉I/O设备 , 要进行输入/输出操作 , 于是就会交给I/O设备去工作 , 任务完成后 , 会把状态寄存器里面的状态标记为完成 。
状态寄存器 , 目的是告诉CPU , 现在已经在工作或工作已经完成 , 如果已经在工作状态 , CPU再发送数据或者命令过来 , 都是没有用的 , 直到前面的工作已经完成 , 状态寄存标记成已完成 , CPU才能发送下一个字符和命令 。
CPU通过读、写设备控制器中的寄存器来控制设备 , 这可比CPU直接控制输入输出设备 , 要方便和标准很多 。
另外 , 输入输出设备可分为两大类:块设备(BlockDevice)和字符设备(CharacterDevice) 。
块设备 , 把数据存储在固定大小的块中 , 每个块有自己的地址 , 硬盘、USB是常见的块设备 。
字符设备 , 以字符为单位发送或接收一个字符流 , 字符设备是不可寻址的 , 也没有任何寻道操作 , 鼠标是常见的字符设备 。
块设备通常传输的数据量会非常大 , 于是控制器设立了一个可读写的数据缓冲区 。
CPU写入数据到控制器的缓冲区时 , 当缓冲区的数据囤够了一部分 , 才会发给设备 。
CPU从控制器的缓冲区读取数据时 , 也需要缓冲区囤够了一部分 , 才拷贝到内存 。
这样做是为了 , 减少对设备的操作次数 。
那CPU是如何与设备的控制寄存器和数据缓冲区进行通信的?存在两个方法:
端口I/O , 每个控制寄存器被分配一个I/O端口 , 可以通过特殊的汇编指令操作这些寄存器 , 比如in/out类似的指令 。
内存映射I/O , 将所有控制寄存器映射到内存空间中 , 这样就可以像读写内存一样读写数据缓冲区 。
I/O控制方式
在前面我知道 , 每种设备都有一个设备控制器 , 控制器相当于一个小CPU , 它可以自己处理一些事情 , 但有个问题是 , 当CPU给设备发送了一个指令 , 让设备控制器去读设备的数据 , 它读完的时候 , 要怎么通知CPU呢?


推荐阅读