Linux PC 开机全过程

1.2.1 中断

中断

我们先说说没有中断的情形,然后你就会懂为何要有中断这个东西。
CPU主要由CU和ALU组成。控制单元(Control Unit)负责动态地控制CPU的行为,它很聪明但是不负责计算。算数逻辑单元(Arithmetic Logic Unit)由一群书呆子构成,你把1和2扔给加法器就会得到3,把2和3扔给乘法器就会得到6,让4左移1位就会得到8,算得很快但是没有智慧。

想象你回到了几十年前,当时最先进的CPU,1秒钟有10万个CPU周期。
假设你写了一段代码,作用是y=f(x),f可能是个非常复杂的函数。
如果没有任何外置设备,那么你只能每次修改x的值-->重启-->计算新的的y值。你甚至无法真正看到y的值,因为没有任何外置设备去导出它。
后来有很聪明的人把打字机和电脑连接在一起,你按ABCDEFG都会触发不同的逻辑电路结果,CPU对应的某些针脚就会有不同的电压变化。通过识别这些电压变化,CPU就可以算出来你到底按了A还是B。你开发了这个软件,大概需要0.001s(100个CPU周期)能识别一次。你希望控制灵敏度大致为0.1秒,因此你写了一个for循环:每1万个CPU周期中,消耗100个CPU周期去识别键盘,剩下9900个周期去执行y=f(x)。
这个for循环看起来可以正常工作,但是你立马意识到了背后的问题:如果今后有更多的外置设备、消耗更多的CPU周期去识别和等待,你将只能有极少的CPU周期留给y=f(x)。
更进一步,你发现其实它并不真的能正常工作:你必须刚好在0.001s的窗口时间内按下按键,否则识别程序没有运行——你找到了按坏3把Cherry键盘背后的真正原因。

解决方案
首先,我们要给键盘配备一个芯片K,专门用来运行你写的识别程序。任何时间按下按键,芯片K都会记录下来,并且放到一个很小的存储芯片S中。K和S专为键盘定制,指令集效率高,只需要50个CPU周期就能完成识别,芯片成本很低,人人都买得起。
然后,CPU不再直接和键盘相连,而是和K相连。K识别的按键事件,就会将CPU特定的针脚拉高(或者拉低),通知CPU“键盘被人按下啦”。
CPU内部有专门的硬件去识别这个通知,如果此时控制寄存器CR0的中断标志位为“能”,那么CPU就会放下手头的工作(中断了当前任务),调用响应这个事件的函数(中断处理函数),完成以后再回来继续手上的任务如y=f(x)。
如此,CPU就不必时时刻刻留意各种外设的存在,绝大部分CPU周期都可用于y=f(x)的计算。只有当中断发生,并且CPU的中断控制位位启用,才会产生相应的开销。