1. 硬件中断
概念
一种由计算机硬件设备发起的信号,用来打断CPU当前正在执行的程序要求CPU来立即处理某个紧急或重要的事件
即CPU收到中断后必须立即停下当前程序去执行中断服务程序,处理完后再处理停下的程序
鼠标和键盘输入:每次按键都会触发一次中断,CPU立即读取这个字符

中断向量表就是操作系统的一部分,启动就加载到内存中了
通过外部硬件中断,操作系统就无需对外设进行轮询或者周期性检测了
由外部设备触发的,中断系统运行流程,叫做硬件中断
上图的流程如下
外设就绪(例如键盘按下按键)
就绪的外设向中断控制器发送中断请求信号,说我有数据或事件要处理
通知CPU中断控制器收到设备请求向CPU发送中断信号,打断CPU当前任务
CPU收到中断信号,向中断控制器查是哪个设备/事件的请求来得到对应的中断号n(每个设备/事件对应唯一的中断号)
CPU暂停当前任务前,将当前寄存器状态保存,确保后续恢复
CPU根据中断号n去中断向量表中找到对应的中断处理程序的入口地址,跳转执行对应的中断服务
中断处理程序执行完毕后,CPU恢复寄存器状态,继续执行原来的工作
上述流程的事件为(时钟事件、异常事件、外设错误事件)
由上可得操作系统内部存储了各种处理中断的不同方法。OS并不关系外设是否就绪只用等待CPU通知。
2. 时钟中断
进程可以在操作系统指挥下被调度,被执行,那操作系统自己由谁指挥,谁推动执行呢?
外部设备可以触发硬件中断,但是这个是需要用户或设备自己触发,那有没有自己可以定期触发的设备呢?

上图流程如下
1.外部设备或内部事件就绪
发起中断请求
中断控制器通知CPU
cpu取得中断号
CPU保存当前寄存器状态,同时暂时屏蔽同级别和低级别的中断(避免当前中断被频繁打断)
查找并执行中断处理程序
恢复现场(之前的任务) ,解除屏蔽中断,恢复工作
内部事件(如时钟异常):让中断不仅能处理外部设备还能相应系统/程序内部需求
进程调度:时钟中断会触发进程调度,实现多任务切换(例如让不同程序轮流占用CPU)
时钟事件: 系统内置的定时硬件,按照固定频率来触发时钟中断,用于更新系统时间,触发进程调度。(频率越高定时更精确,系统相应更迅速,中断处理开销也更大,消耗更多CPU时间)
时钟中断通常是最高优先级的中断之一不能被屏蔽(NMI除外),所以可以通过强制的时间限制来防止单个进程垄断CPU
操作系统在硬件时钟的推动下就能自动调度了(时钟中断是操作系统主动获取控制权的手段)。
所以,什么是时间⽚?CPU为什么会有主频?为什么主频越快,CPU越快?
- 时间片是操作系统分配给每个可运行进程的一段连续的,不被中断的CPU执行时间。
时钟中断时,CPU会暂停当前进程,执行中断服务程序里的进程调度。
进程调度的核心是检查当前进程的时间片是否用完,用完了就切换到下一个等待的进程,给它分配新的时间片,没用完就让它继续占用CPU。
- 主频本质是CPU内部时钟发生器的震荡频率决定了CPU每秒能完成多少次基础操作。例如一个1+1的指令需要三步
控制器从内存取指令
运算器计算1+1
结果存回寄存器
每一次震荡CPU就能完成一步基础操作
- 所以主频越快每秒震荡次数越多,执行指令就越快
主频与时钟中断的联系
主频是时钟中断的速度基准
主频越高能支持的时钟中断频率就越高
主频是心跳速度,时钟中断就是心跳的功能触发键。
3. 软中断
上部外部硬件中断,需要硬件设备触发
软件原因也可以触发上面的逻辑
为了让操作系统支持系统调用,CPU也设计了对应的汇编指令(int或者syscall),可以让CPU内部触发中断逻辑
例如缺页中断,内存碎片处理、除零错误、野指针错误,这些问题都会被转换为CPU内部的软中断,然后执行中断处理完成所有处理。有的是进⾏申请内存,填充页表,进⾏映射的。有的是⽤来处理内存碎片的,有的是⽤来给⽬标进⾏发送信号,杀掉进程等等。

如上图,在处理硬件需求时也会处理用户请求的内核功能,本质把中断机制的被动响应扩展为了主动交互+被动响应的统一入口。

上图实际是一个函数指针数组,存储了各种系统调用方法。所以每个系统调用都有唯一的下标(系统调用号)
用户层怎么把系统调用号给操作系统---> 寄存器 例如EAX
操作系统怎么把返回值给用户? --->寄存器或用户传入的缓冲区地址
系统调用的过程就是先int 0x80 syscall 陷入内核,本质为触发软中断,CPU自动执行系统调用的处理方法,这个方法根据系统调用号自动查表执行对应方法
系统调用号的本质是数组下标
我们并不会直接调用这里的函数,使用fork、open、read等。即我们平时所用的函数并不是真正的系统调用,Linux的gnu C标准库,给我们把⼏乎所有的系统调⽤全部封装了。原因是OS为了自我保护。
操作系统就是躺在中断处理例程上的代码块
CPU内部的软中断例如 int 0x80或syscall,调用内核功能(例如读写文件)出现的,由程序发起的可控异常(会继续执行下一条指令) 我们叫做陷阱
除零/野指针/缺页导致的段错误,我们叫做异常(例如缺页异常)
4. 内核态和用户态
虚拟地址空间分为两大部分,1GB内核区,3GB用户区,不同PCB虚拟地址空间的用户页表不同但是内核页表相同。
操作系统无论怎么切换进程都能找到同一个操作系统,即操作系统 系统调用方法的执行是在进程的地址空间中执行的。
进程执行的本质是在地址空间上跳转,用户在写程序时不就能直接去访问吗??
用户态与内核态用于区分进程运行中两种不同权限级别防止用户程序直接访问和操作关键系统资源
**内核态:**特权模式,CPU在此模式可以执行所有指令,访问所有内存和硬件,只有操作系统内核在此模式下运行
**用户态:**用户模式,CPU只能执行受限的指令子集,只能访问自己的内存空间,所有程序都在此模式下运行。
模式切换
从用户态 → 内核态
系统调用:主动请求服务(read, write, fork等)
异常:程序出错(除零、页错误、非法指令)
硬件中断:时钟中断、设备中断
从内核态 → 用户态
系统调用返回:完成服务后返回
进程调度:切换到另一个用户进程
中断/异常处理完毕:返回被中断的用户程序
这篇就到这里啦(づ ̄3 ̄)づ╭❤~ (๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤