目录
一、硬件中断
为引出今天的话题,我们来思考这样一个问题:
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
return 0;
}
当以上程序执行到scanf时,如果我们不输入信息,程序会一直阻塞在这里。那程序如何知道我们已经完成输入了呢?而且我们输入的信息在外设上,程序又是如何知道何时将其载入内存的呢?
这其实是由外设就绪后通知给CPU,再由CPU通知给操作系统,然后由操作系统调用最后通知给前台程序。具体细节如下:
每个中断都有自己的编号,即中断号,在中断控制器中会有寄存器来记录已就绪的中断号。一旦有外设就绪,它的中断号将被存入寄存器,然后由中断控制器通知CPU。CPU得到信息后会从中断控制器的寄存器中获取中断号,并停止当前工作,保持好当前数据(保存上下文),然后通知操作系统执行对应的中断方法。处理完后,CPU恢复现场,继续之前的工作。
如上图所标记的执行顺序:1,2,3,4,5,6,7。
我们都知道CPU运行速度非常快,外设的数据不能直接与CPU打交道,而是要通过存储器作为桥梁。注意这只是说外设的数据不与CPU打交道,不代表外设就不与CPU打交道,如下冯·诺伊曼体系结构:
OS(操作系统)中储存了各种处理中断的不同方法,通过上面的执行逻辑我们可以知道,OS并不需要关心外设是否就绪,只需要等待CPU通知即可。
像这样由硬件产生的中断叫硬件中断,同理就有软件中断。下文会细讲。
二、时钟中断
我们回顾一下,操作系统是一个对软硬件进行管理的软件,它的工作通常包括:进程调度,为程序提供系统调用。
其实操作系统做的所有工作都是一种中断处理。
那么当没有中断需要处理时,操作系统在做什么?
这个时候操作系统什么也不干,就暂停在那里。对,你没听错,操作系统也是牛马啊!CPU没给它派发中断任务,它就只管闲着就好。
OS做的任何工作都是对中断的处理,那么OS进行进程调度也是收到中断信号吗?
是的!除了以上讲的外设会生成中断信号以外,还有一个特殊的设备:“时钟源”,它被集成在CPU内部,会以特定的频率向CPU发送中断,这也就是时钟中断。
OS在接收到时钟中断信号后,更新当前进程的时间片,并检查时间片是否耗尽(即计数器是否为0)。如果已经耗尽,则进行进程调度,如果没有,则无需任何操作。
注意:时钟中断的频率是固定的,而进程的时间片是根据具体情况动态调整的。
总结:操作系统是基于中断机制进行工作的软件。
三、软中断
除了硬件产生中断以外,在程序中写的系统调用也会产生中断,我们把这种由软件触发的中断叫作软中断。
也就是说CPU也可以主动的触发中断,并不一定是由硬件触发。
缺⻚中断?内存碎⽚处理?除零野指针错误?这些问题,全部都会被转换成为CPU内部的软中断,然后执行中断处理例程,完成所有处理。有的是进⾏申请内存,填充⻚表,进⾏映射的。有的是⽤来处理内存碎⽚的,有的是⽤来给⽬标进程发送信号,杀掉进程等等。
又比如在处理系统调用产生的中断方法中,有着这样一张表:
它实际上是一个函数指针数组,储存了各种系统调用方法。 所以每一个系统调用都有唯一的下标,这个下标也叫作系统调用号。
但我们会发现这些函数好像都没用过,然而名字却有些熟悉。确实,我们并不会直接调用这里的函数,而是使用fork,read,write,open等。也就是说我们平常所用的这些函数并非真正意义上的系统调用,而是在系统调用的基础上进行封装的。OS把它做得这么复杂也是为了自我保护。
比如我们用的read函数里面封装了这样的汇编代码:
int 0x80 move eax 5
- int 0x80:让CPU产生软中断,也可以通过syscall触发
- move eax 5:把read的系统调用号5存入寄存器。
通过int 0x80找到这样的中断方法:
void CallSystem() { //获取系统调用号 int n = 0; move n eax //... ... //系统调用方法 sys_call_table[n](); }
四、用户态与内核态
虚拟地址空间分为两大部分,其中1GB是内核区,3GB是用户区。不同的PCB虚拟地址空间的用户页表是不同的,但是它们的内核页表是相同的。如下:
这也说明,无论操作系统怎么切换进程,都能通过内核区找到同一个操作系统。即操作系统调用方法的执行是在进程的地址空间中进行的。
而进程执行的本质也是在地址空间上跳转,那么用户在写程序时不就可以直接去内核地址空间访问内核了吗。
这样的情况确实可以实现,因此为保护操作系统内核安全,就引入了一系列的权限机制。
比如用户态和内核态就是一种权限,在CPU中存在一个寄存器CPL标记当前所处的权限,0表示内核态,3表示用户态。
在进行系统调用时就需要进行权限的更改,比如int 80或syscall在触发中断时也进行权限的更改,使其陷入内核。
非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!