前言
这里的中断和异常指的是处理机的中断和异常,处理机可以理解为cpu。
正文
中断是怎么产生的呢?
是因为操作系统的诞生,引入了中断机制,用来实现多道程序的并发。
简单点说就是这样子的,以前是一道一道程序执行,现在多道程序要想并发执行,其中一种方式就是一个程序运行一下子,然后中断,下一个程序运行一下子。。。。
中断操作发送的时候以为着操作系统介入,开展管理工作。
cpu收到计时部件(固件,固件的操作是操作系统操控的)发出的中断信号,切换为核心态对中断进行处理。
也就是说cpu 从用户态切换到核心态,操作系统负责中断信号处理。
然后就切换到了核心态,那么这个时候操作系统开始运行进程1切换到进程2了。
切换完后,那么交给进程2去运行。
如果进程在运行的时候出现了内中断(系统调用,主动请求操作系统介入),请求输出,比如说需要打印。cpu 切换为核心态,对中断进行处理。
操作系统对中断信号进行处理,然后操作系统去操作打印机进行打印,打印机开始工作,进程暂停运行等待i/o完成,切换其他进程进行运行,又切换到了用户态。
当io操作完成后,通知cpu发出中断信号,操作系统对中断信号进行处理,然后切换为那个等待i/o操作的进程。
那么问题来了,cpu是如何通知操作系统的?cpu能通知操作系统?
其实这就是涉及到一个问题,那就是cpu本身就有程序的。
在启动引导阶段,操作系统会给CPU提供一张中断描述符表。这张表预定义了操作系统为CPU提供的一系列处理函数,用于处理可能会遇到的异常。
由于操作系统提供了一个函数指针来处理段错误(Page Fault),所以当我们试图访问地址为99999999999999 时,CPU会跳转到该处理函数,从而将控制权转交给操作系统。
接着,操作系统就会打印一段友好的提示消息,通知我们发生了段错误。因为是操作系统输出的消息,所以这个消息可能因操作系统的不同而有所差异。
这个故事告诉我们,其实我们程序占用的只有cpu,一但cpu做不来的时候,那么这个时候就要请求操作系统去执行。
这里再说一下为啥i/o操作不需要cpu持续运作,是这样的:
I/O发展是经过一下一步步发展的
1. CPU直接控制外围设备(硬盘磁带等), 在简单微处理器中常用
2. 增加I/O模块, 将CPU与外围设备解耦, CPU只与I/O模块打交道. 只需定义好接口, CPU厂商和外围设备厂商就可以相互根据接口开发, 互不影响
3. 增加中断方式, 还是经过I/O模块, 只不过I/O模块完成之后, 只需通知CPU即可, CPU在等待阶段完全可以去做其他事情, 提高CPU利用率.
4. I/O模块增加DMA控制器. 之前的阶段是每次只传输一个字, 就通知CPU, 就发起一次中断, CPU放到寄存器中, 再放到内存中. 这样CPU就会被连续的中断打断, 不断切换进程,
上下文, 效率很低.DMA控制器类似于一个小的CPU, 有自己的寄存器(记录主存地址和取到的字的count等). CPU可以发起一个DMA请求, 传入读写操作类型, 相关I/O设备地址, 内存的起始地址,
要操作的字数.然后DMA就可以获取总线的控制权, 将一大块内存和外部I/O读入或写出.等操作完成后, 再通知CPU. 释放总线控制权.
缺点是:系统总线也是一种资源, DMA操作期间, 当处理器需要访问总线时, 执行速度会变慢.但是总得来说, DMA是一种高效传输方式.
总结一下:
用户态到核心态切换是通过中断来实现的,而且是唯一实现方式。
核心态到用户态的切换是通过执行一个特权指令,就是将程序状态字的标准设置为用户态即可。
如何区分内中断还是外中断
中断分为内中断和外中断。内中断(也称异常、例外、陷入)信号来源是CPU内部,与当前执行的指令有关,外中断(狭义的中断)信号的来源是CPU外部,与当前执行的指令无关。
内中断可以分为自愿中断和强迫中断,自愿中断是指指令中断,如系统调用时使用的访管指令(又叫陷入指令、trap指令),强迫中断是指硬件故和软件故障(如整数除0)。
内中断还可以分为陷入(trap)、故障(fault)和终止(abort)。陷入指有意而为之的异常,如系统调用。故障指由错误条件引起的,可能被故障处理程序修复,如缺页。终止指不可恢复的致命错误造成的结果,终止处理程序不再将控制返回给引发终止的应用程序,如整数除0。
外中断可以分为外设请求(如I/O操作完成发出的中断信号)和人工干预(如用户强行终止进程)。
外中断的处理过程
解释一下:
是这样子的,程序在用户态执行的,时候呢,执行一条指令,cpu 后面执行的指令是去检查有无外部中断信号。
如果有的话,那么会将当前状态保存。我们知道中断的时候呢,这个时候就是操作系统运行的时候了,cpu 回调操作系统程序,当操作系统程序执行完毕,切换会用户态,然后继续执行原理的指令。