系统调用、异常和中断
此篇博客针对清华大学陈渝老师的操作系统课程的对应内容。
关于中断、异常、系统调用。实际并没有严格的区分,不同体系结构都有其自己的一套规定,陈渝老师这部分的内容,将三者严格区分,忽略了三者的联系,所以显得比较混乱。
我根据Intel体系结构中对这部分内容的规定以及黑皮书,重新梳理了陈渝老师本节课的内容,
主要涉及定义及关系的梳理,具体细节不过多阐述,希望能够帮助使一些人有更深的理解。
引入
OS为用户提供用户接口(如shell和GUI)使用计算机,同时为应用程序提供了方法去获得OS的服务,这种方法就是系统调用。系统调用涉及到的异常和中断,是较重要的内容,尤其是中断操作。
中断、异常、系统调用
简单一句话串联起这三个东西就是:应用程序请求系统调用时会发出trap信号(一种异常),有异常就要处理异常,即通过中断处理程序回应系统调用的请求。
CPU的执行状态:内核态和用户态
- 内核态 也称管态、系统态
此状态的CPU拥有较高的权限,能执行一切指令、访问所有的寄存器和存储区。 - 用户态 也称目态
它拥有较低的权限,仅能执行规定指令,访问限定的寄存器和存储区。
设置内核态的关键原因就是,防止OS的关键数据被应用程序有意或无意的篡改。一般而言,应用程序运行在用户态,不能执行OS指令及访问OS空间,这题可以防止应用程序对OS的破坏。
系统调用
系统调用是OS提供应用程序去获取OS服务的一种方法,实际是发出了陷阱信号(trap), 启动异常处理程序,使OS由用户态转变为内核态,这样就能够由OS完成一些应用程序做不到的事情a。
由于内核态更靠近OS的底层,CPU的执行过程就像掉入了一个"陷阱"(本来在处于"外层",突然需要响应系统调用来到了"底层")。
模式切换本身也是有代价的,但正是这些代价,才为应用程序提供了简单的接口去使用系统资源,才保证了OS的安全性可靠性。
这些代价将会在文章最后分析。
什么是异常?
异常有三种:陷阱(trap)、错误(fault)和终止(abort)。
在收到异常信号时,CPU就会在完成当前执行指令后暂停该程序,转向执行相应的异常处理程序。
- 陷阱(trap):陷阱是有意的异常,由应用程序主动发出,完成异常处理程序之后会转回原程序的下一条指令。通常是为了实现系统调用,其异常处理程序就是回应应用程序请求的服务请求。
- 错误(fault):错误是一种可能被修复的异常,若异常处理程序可以修复错误,则返回原程序,重新执行当前程序;若不能修复,则终止程序。最典型的例子就是缺页。
- 终止(abort):十分严重的错误,异常原因无迹可循,会终止程序或任务的执行,无法恢复。
中断(广义)的分类
Intel体系结构考虑到异常处理和中断处理的机制近乎相同,就把异常归为广义上中断的一种。这里我们主要遵循Intel的规定。
广义的中断分为两种:外中断和内中断,
- 外中断:(狭义的中断)中断信号来自CPU外部,与CPU无关。
- I/O中断
- 时钟中断
- 内中断:也称“异常”,中断信号来自CPU内部,来自正在执行的进程
- 陷阱
- 错误
- 终止
黑皮书上采用MIPS体系结构,则将中断归为异常的一种,即异常包括中断、陷阱、错误和终止。
操作系统模式转换的代价
- 中断处理机制需要维护一个中断向量表,保障中断号与中断服务的映射关系
- 验证系统调用的安全性
- 内核态的操作系统,需要维护一个内核的堆栈,以服务内核进程
- 内核堆栈内的数据需要转移到内存