概述
- 操作系统负责什么时候切换到另一个任务,以及切换到哪一个任务执行;
- 处理器只负责具体的切换过程,包括保护前一个任务的现场。操作系统只执行了一个call/jmp/iret的指令,但是处理就完成了任务的切换。
- 协同式任务切换方式 从一个任务切换到另一个任务,需要当前任务主动地请求暂时放弃执行权,或者在通过调用门请求操作系统服务时,由操作系统“乘机”将控制转移到另一个任务。
- 抢占式任务切换方式 在这种方式下,可以安装一个定时器中断,并在中断服务程序中实施任务切换。硬件中断信号总会定时出现,不管处理器当时在做什么,中断都会适时发生,而任务切换也就能够顺利进行。
15.1 本章代码清单
15.2 任务切换前的设置
- 创建和执行操作系统的0特权级任务,任务管理器
要执行任务切换,系统中必须至少有两个任务,而且已经有一个正在执行中。
- 创建TSS内存区域:没有LDT,不需要创建额外的栈
- 创建TSS描述符,并加载到GDT中
- 将TSS选择子传送到任务寄存器TR中(处理器会将TSS描述符中的B置1)
15.3 任务切换的方法
- 中断,这是现代抢占式多任务的基础。
- 保护模式下,中断向量表不再使用,取而代之的是中断描述符表,保存的是门描述符。
- 任务门描述符
* TSS选择子,任务门应当指向任务的TSS。
* P位,指示该门是否有效,当P位位“0”时,不允许通过此门实施任务切换。
* DPL位,任务门描述符的特权级,但是对因中断而发起的任务切换不起作用,处理器不按特权级施加任何保护。
- EFLAGS的“NT”位,嵌套任务标志(Nested Task Flag)
- 如果当前任务EFLAGS寄存器的NT位是“1”,则表示当前正执行的任务嵌套于其他任务,并且能够通过TSS任务链接域的指针返回到前一个任务。
- 中断切换任务时,旧任务的“B”位和“NT”位不会改变,新任务的“B”位置“1”,“NT”位置“1”。
- 用远过程调用指令CALL,或者远跳转指令JMP直接发起任务切换
- 使用CALL指令调用时,“B”位和“NT”位的改变和中断切换一样。
- 使用JMP指令调用时,不会形成任务之间的嵌套。
- 处理器固件会检测新任务TSS描述符的B位,如果为“1”,则不允许执行这样的切换。
- iret切换任务
- CALL和中断后,可以用iret返回到上一个任务,旧任务的“B”位和“NT”位都置“0”。
15.4 用call/jmp/iret指令发起任务切换的实例
主要是通过理解代码的细节来理解这几个指令的切换任务的功能。
15.5 处理器在实施任务切换时的操作
- 处理器通过以下4种方法将控制转换到其他任务:
- jmp或者call到GDT内的某个TSS描述符
- jmp或者call到某个任务门描述符
- 异常或者中断发生时,其信号指向中断描述符表内的任务门
- EFLAGS寄存器的NT位置置位的情况下,当前任务执行了一个iret指令
- 任务切换时,处理器的操作 取TSS描述符选择子 -> 检查DPL -> 设置EFLAGS的“NT”和“B”标志位 -> 用新任务的TSS选择子和TSS描述符价值任务寄存器TR -> 新任务的TSS状态数据被加载到处理器 -> 与段选择子相对应的描述符在经过验证后也被加载 ->开始执行新任务