所谓上下文切换,实质就是寄存器堆的切换过程。这其中一部分需要硬件来切换,一部分需要软件来处理。
当在用户空间发生中断时,首先由 x86 CPU 从硬件角度进行处理,然后才是 linux 内核的处理。当中断处理完毕,返回到用户空间时,最后的步骤也是交给 CPU 硬件来处理的。
1、 X86 CPU 对中断的硬件支持
CPU 从中断控制器取得中断向量
根据中断向量从 IDT 中找到对应的中断门
根据中断门,找到中断处理程序
在进入中断处理程序前,需要将堆栈切换到内核堆栈。也就是将 TSS 中的 SS0、ESP0装入SS、ESP
然后将原来的用户空间堆栈(SS, ESP)、EFLAGS、返回地址(CS, EIP)压入新的堆栈。
以上这一系列动作都由硬件完成
最后,才进入中断处理程序,接下来,由 linux 内核处理
2、 Linux 内核对中断的处理
保存中断来源号
调用 SAVE_ALL,保存各种寄存器
将 DS、ES 指向 __KERNEL_DS
将返回地址 ret_from_intr入栈
调用 do_IRQ进行中断处理
中断处理完毕,返回到 ret_from_intr
3、 ret_from_intr
所有的中断处理程序在处理完之后都要走到这里;
判断进入中断前是用户空间还是系统空间
如果进入中断前是系统空间,则直接调用 RESTORE_ALL
如果进入中断前是用户空间,则可能需要进行一次调度;如果不调度,则可能有信号需要处理;最后,还是走到 RESTORE_ALL
RESOTRE_ALL 和 SAVE_ALL 是相反的操作,将堆栈中的寄存器恢复
最后,调用 iret 指令 ,将处理权交给 CPU
4、 iret 指令使 CPU 从中断返回
此时,系统空间的堆栈和CPU在第1步处理完之后,交给 linux 内核时的情形是一样的,也就是保存着用户空间的返回地址(CS、EIP)、EFLAGS、用户空间的堆栈(SS、ESP)。
CPU将 CS、EIP、EFLAGS 、SS、ESP恢复,从而返回到用户空间。
阅读(1411) | 评论(0) | 转发(0) |