操作系统的心脏节拍:CPU中断如何驱动内核运转?

目录

一、硬件中断

二、时钟中断

三、软中断

四、用户态与内核态


一、硬件中断

为引出今天的话题,我们来思考这样一个问题:

cpp 复制代码
#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函数里面封装了这样的汇编代码:

cpp 复制代码
int 0x80 
move eax 5
  • int 0x80:让CPU产生软中断,也可以通过syscall触发
  • move eax 5:把read的系统调用号5存入寄存器。

通过int 0x80找到这样的中断方法:

cpp 复制代码
void CallSystem()
{
    //获取系统调用号
    int n = 0;
    move n eax
    //... ...
    //系统调用方法
    sys_call_table[n]();

}

四、用户态与内核态

虚拟地址空间分为两大部分,其中1GB是内核区,3GB是用户区。不同的PCB虚拟地址空间的用户页表是不同的,但是它们的内核页表是相同的。如下:

这也说明,无论操作系统怎么切换进程,都能通过内核区找到同一个操作系统。即操作系统调用方法的执行是在进程的地址空间中进行的。

而进程执行的本质也是在地址空间上跳转,那么用户在写程序时不就可以直接去内核地址空间访问内核了吗。

这样的情况确实可以实现,因此为保护操作系统内核安全,就引入了一系列的权限机制。

比如用户态和内核态就是一种权限,在CPU中存在一个寄存器CPL标记当前所处的权限,0表示内核态,3表示用户态。

在进行系统调用时就需要进行权限的更改,比如int 80或syscall在触发中断时也进行权限的更改,使其陷入内核。

非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!

相关推荐
Vcaker3 分钟前
Linux学习36-k8s集群升级及kube-vip高可用
linux·运维·学习
起个名字费劲死了9 分钟前
VisionMaster集成深度学习算法(基础狗)
人工智能·深度学习·算法
lengxuenong13 分钟前
枚举例题分析
c++·算法·青少年编程
wdfk_prog17 分钟前
Wi-Fi Direct教程 02:从 wpa_cli main() 到 P2P_FIND——用源码注释追踪 CLI 控制命令发送
运维·服务器·网络·网络协议·ubuntu·p2p·wifi-direct
“AI国潮设计-小江”24 分钟前
【SDXL实战】用AI生成“财神爷蛋糕×英歌舞人物”潮汕国潮甜品IP,附Prompt与批量生成思路
开发语言·人工智能·python·aigc
skywalk816327 分钟前
Deepseek harness的4种模式 配置文件内容
linux·人工智能·ubuntu·deepseek·harness
Navigator_Z31 分钟前
LeetCode //C - 1269. Number of Ways to Stay in the Same Place After Some Steps
c语言·算法·leetcode
Behavior33 分钟前
OpenAI 发布 GPT-6.1 Sol,能力逼近 Astra
aigc·openai·ai编程
2601_9657422234 分钟前
短视频脚本创作方法分享:本地生活类账号的起步思路
大数据·人工智能·算法·ai·新媒体运营·生活
55873生态系统手记42 分钟前
读完 55873 资产钱包的技术栈,我重新理解了 "合规钱包" 应该长什么样
算法·架构