任务
引起任务切换的四种情况:
1, 当前任务执行转移到TSS描述符的JMP或CALL指令
2, 当前任务执行转移到任务门的JMP或CALL指令
3, 中断或异常索引IDT中的任务门.
4, 在NT标志被置位时,当前任务执行IRET指令
任务切换的步骤:
1,检查当前任务是否允许切换到新任务,TSS描述符和任务门的DPL>RPL和CPL.
2,检查新任务的TSS描述符是否被标记为存在和段限有效(>=67H).
3,保存当前任务的状态.
4,将指向新任务的TSS描述符的选择符装入TR,置位新任务的忙位,置位CR0中的TS位.
5,从新任务的TSS装入它的状态并且继续执行.(LDTR,CR3,EFLAGS,EIP…)
在任务切换期间所作的检查
步骤 检查的条件 异常 出错代码引用
1 TSS描述符是否在存储器 NP 新任务的TSS
2 TSS描述符非忙 TS(对IRET) 任务的返回链路的TSS
GP(对JMP.
CALL,INT)
3 TSS段限>=108 TS 新任务的TSS
4 寄存器用TSS中的值装入
5 新任务的LDT选择符有效 TS 新任务的LDT
6 代码段的DPL匹配选择符的RPL TS 新代码段
7 SS选择符有效 TS 新堆栈段
8 堆栈段在存储器中 SF 新堆栈段
9 堆栈段的DPL匹配CPL TS 新堆栈段
10 新任务的LDT在存储器 TS 新任务的LDT
11 CS选择符有效 TS 新代码段
12 代码段在存储器 NP 新代码段
13 堆栈段的DPL匹配选择符的RPL TS 新堆栈段
14 DS,ES,FS,GS选择符有效 TS 新数据段
15 DS,ES,FS,GS段是可读的 TS 新数据段
16 DS,ES,FS,GS段在存储器 NP 新数据段
17 DS,ES,FS,GS段的DPL>=CPL TS 新数据段
(除非这些段是依从段)
注:NP=段不存在异常 GP=一般保护异常 TS=无效TSS异常 SF=堆栈异常
任务嵌套(任务链)
当中断,异常,跳转或调用引起任务切换时,处理器把对应于当前状态段的选择子复制到新任务的TSS中.并置位NT标志.
TSS链路子段和NT标志用于把执行返回到先前的任务.NT标志(EFLAGS中)指明当前执行的任务是否被嵌套早另一个任务的执行中.
新任务通过执行IRET指令而释放控制.当IRET指令被执行时,NT标志被检查.
任务切换对忙位,NT位和链路字段上的影响
字段 JMP指令的影响 CALL指令的影响 IRET指令的影响
新任务忙位 1(之前必须清0) 1(之前必须清0) 不变(之前必为1)
拉任务忙位 0 不变(目前是1的) 0
新任务NT 不变 1 不变
老任务NT 不变 不变 0
新任务Link字段 不变 用老任务TSS选择子装入 不变
老任务Link字段 不变 不变 不变
注:NT和IRET可被任何级上的软件执行来引起任务切换,为防止错误的任务切换成功.OS应初始化它建立的每个每个TSS的链路子段.
忙位防止发生循环
TSS描述符的忙位用于防止重新进入任务切换.
处理忙位的方式:
1,当切换到一任务时,处理器置位新任务的忙位
2,当从一任务切换时,如果该任务不被置入链中(即引起任务切换的指令是JMP或IRET指令),处理器就清0老任务的忙位.否则忙位保持.
3,当切换到一任务时,如果新任务的忙位已被置位,则处理器产生一般保护异常.
修改任务的链接:
为了恢复一个被中断的任务,并且是在中断它的任务之前,可能需要修改被挂起的任务的链,可靠步骤为:
1,禁止中断
2,首先改变中断者任务的TSS中的链路字段,然后清除被从链中去掉的任务的TSS描述符中的忙位.
3,开启中断.
可以通过将两个任务的页目录(CR3)设置为相同来共享.也可以通过将两个任务的LDT设置为同一个LDT选择子来共享