0%

调试分析 Linux 0.00 多任务切换

调试分析 Linux 0.00 多任务切换

执行 153 行 iret 时栈的变化

执行前栈的内容

image-20220504154137710

执行后栈的内容

image-20220504154156025

在执行前后进行了栈的切换,从任务0的内核栈切换到了任务的用户栈。

模式切换

当进入和退出 system_interrupt 时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?

在进入中断时,通过查询IDT表,获得索引,之后进行特权级检查,要求CPL<=调用门DPL;RPL<=调用门DPL。DPL<=CPL。特权级检查通过,则特权级改变。栈也进行切换。处理器从当前任务的TSS段获得该中断使用的堆栈的段选择符与栈指针,然后把被中断的栈选择符与栈指针压入新栈。EFLAGES、CS、EIP的值也被压栈。

当退出时,使用iret指令。把保存的寄存器内容恢复到EFLAGES中,完成特权级复原,即切换为3。同时栈也切换回原来的栈。

任务切换过程

当时钟中断发生,进入到 timer_interrupt 程序,请详细记录从任务 0 切换到任务 1 的过程。

image-20220504170543986

以本图为例分析。说明第一次切换时的状况,第一次切换,即时钟中断发生时,大概率会在227行,此时任务号为0,当跳入时钟中断后,从125行开始进行转换,首先将1写入寄存器eax,然后判断,因为此时任务号为0,所以不执行127行,执行128行,则将任务号改为1,然后在129行跳转到任务1的代码段。

任务0时的寄存器如下:

img

任务1时的寄存器如下:

image-20220504205616009

任务切回过程

又过了 10ms ,从任务1切换回到任务 0 ,整个流程是怎样的? TSS 是如何变化的?各个寄存器的值是如何变化的?

image-20220504170543986

如图,承接上题叙述,从代码段228执行,在232循环,大概率在循环时进行时间中断发生,在126行比较时,由于此时任务号为1,所以跳转到131行,将任务号设为0,在132行处,跳转到任务0,由于任务0执行到129行,所以从130执行,再跳转到133行,弹栈后通过iret返回,由于上次为在226行触发中断,所以回到226行。

寄存器变化如下:

QQ图片20220504212642

变至

img

下图为任务0的TSS

image-20220504214234727

下图为任务1的TSS

image-20220504214319515

详细总结任务切换的过程

image-20220504170543986

还是对照这张图片,从头来讲。

第一次切换,即时钟中断发生时,大概率会在227行,此时任务号为0,当跳入时钟中断后,从125行开始进行转换,首先将1写入寄存器eax,然后判断,因为此时任务号为0,所以不执行127行,执行128行,则将任务号改为1,然后在129行跳转到任务1的代码段。

从代码段228执行,在232循环,大概率在循环时进行时间中断发生,在126行比较时,由于此时任务号为1,所以跳转到131行,将任务号设为0,在132行处,跳转到任务0,由于任务0执行到129行,所以从130执行,再跳转到133行,弹栈后通过iret返回,由于上次为在226行触发中断,所以回到226行。

然后大概率在此行,再次遇到时间中断,从125行开始进行转换,首先将1写入寄存器eax,然后判断,因为此时任务号为0,所以不执行127行,执行128行,则将任务号改为1,然后在129行跳转到任务1。由于任务1上次执行至

132行,所以从133行开始,到iret返回至232行。

又大概率在232行遇到时钟中断,执行到126行比较后跳转到131行,将任务号变为0,回到任务0的代码段。

至此为一个流程。