linux内核研究笔记2(x86中断和异常调用过程)
中断和异常概况
处理器提供了两种中断程序执行的机制:中断和异常。
尽管处理过程类似,但两种机制有很大区别。其中,中断(interrupt)是一种异步事件,由I/O设备触发;异常(exception)是一种同步事件,当处理器运行指令时检测到一些预定义的条件就会触发,异常分为三类:faults、traps和aborts。
中断和异常的处理过程入口点在IDT表里面,IDT里面有两种门描述符:中断门和陷阱门。两者几乎一样,除了中断门会修改EFLAGS中的IF标志。cpu保留的异常和中断向量如下:
处理器处理过程
如果没有堆栈切换,调用中断或异常的过程如下:
1.push当前EFLAGS、CS、EIP寄存器到堆栈
2.如果有错误码,则push错误码到堆栈
3.从中断门或者陷阱门中取得新代码的段选择符和指令指针,分别加载到CS和EIP中
4.如果调用是通过中断门,则清除EFLAGS中的IF标志
5.开始执行过程代码
如果涉及堆栈切换,则处理器处理过程如下:
1.临时保存(内部)当前SS、ESP、EFLAGS、CS、EIP寄存器
2.从TSS中加载对应特权级的堆栈选择符和堆栈指针到SS和ESP,从而切换到新堆栈
3.将之前临时保存的SS、ESP、EFLAGS、CS、EIP推送到新堆栈
4.如果有错误码,则push错误码到新堆栈
5.从中断门或者陷阱门中取得新代码的段选择符和指令指针,分别加载到CS和EIP中
6.如果调用是通过中断门,则清除EFLAGS中的IF标志
7.开始执行过程代码
以上是中断或异常发生时,进入过程代码的执行步骤,从过程代码返回是通过IRET指令,该指令和RET指令类似,除了IRET需要恢复之前被中断代码执行时的EFLAGS寄存器。
从同一个特权级恢复中断,就是不涉及堆栈切换的过程,返回过程如下:
1.恢复中断和异常之前的CS和EIP寄存器值
2.恢复EFLAGS寄存器
3.适当地递增堆栈指针
4.恢复被中断代码的执行
从不同特权级恢复中断,就是涉及堆栈切换的过程,返回过程如下:
1.执行特权级检查
2.恢复中断和异常之前的CS和EIP寄存器值
3.恢复EFLAGS寄存器
4.恢复中断和异常之前的SS和ESP寄存器,结果就是堆栈切换到了被中断代码执行时的堆栈
5.恢复被中断代码的执行