保护模式及其编程——任务管理

来源:互联网 发布:单片机开发工具 编辑:程序博客网 时间:2024/05/17 08:21
摘要:任务是处理器可以分配、调度、执行和挂起的一个工作单元。用于可执行程序、任务或者进程、操作系统服务、中断或者异常处理过程和内核代码。通过中断、异常、跳转或者调用我们可以执行一个任务。任务描述符表中与任务相关的描述符有任务状态描述符和任务门,当执行权转移到上述任何一种描述符的时候,将会造成任务切换。

任务切换很像过程调用,但是会保存更多的处理器信息。任务切换几乎要保存所有的处理器寄存器信息,同时任务切换是不可重入的,这和过程调用是不同的。任务切换不会把任何信息压入堆栈中,而是把它们保存在TSS中。

1.任务的结构和状态


任务有两部分,任务执行空间和TSS。任务执行空间包括代码段、数据段和堆栈段。TSS执行了执行空间中的各个段,并且为任务状态信息提供存储空间。任务的结构和状态如下图:

一个任务的使用由执行TSS段的选择符来指定,当一个任务被加载进处理器执行时,那么该任务的段选择符、基地址、段限长和TSS描述符都会被加载到任务寄存器TR之中;如果使用了分页机制,那么页目录基地址会被加载到CR3寄存器。当前任务状态由处理器的以下内容构成:
@@@所有通用寄存器和段寄存器信息
@@@标志寄存器、程序指针EIP、控制寄存器CR3、任务寄存器TR、LDTR寄存器
@@@段寄存器指定的任务当前执行空间
@@@IO映射位图基地址和IO位图信息
@@@特权级0~2的堆栈指针
@@@链接到前一个任务的链指针

2.任务的执行


以下方式用于执行一个任务:
1)使用call指令明确调用一个任务
2)使用JMP指令明确跳转到一个任务(linux内核使用的方式)
3)(处理器)隐含地调用一个中断句柄处理服务
4)隐含地调用一个异常句柄处理服务

所有上面的方式,都会使用一个指向任务门或者任务TSS段的选择符来确定一个任务。如果A调用了B,那么A的TSS选择符会被保存在B的TSS中。作为任务切换的一部分,处理器会切换到另一个LDT,从而运行每个任务对基于LDT的段具有不同逻辑到物理地址的转换。

3.任务管理数据结构


处理器定义了以下支持多任务的寄存器和数据结构:任务状态段TSS(注意TSS是一个段)、TSS描述符、任务寄存器TR、任务们描述符、标志寄存器中的NT标志。它们用于完成任务的切换和任务上下文的保存。

3.1.任务状态段


用于恢复一个任务执行的处理器状态信息,注意,这是一个段,它的段选择符在GDT中。32位cpu使用的TSS如下。

TSS中的各个字段分为两类:

1)动态字段:
通用寄存器(EAX~EDX、EBP、ESP、ESI、EDI)/段选择符字段(CS~GS中的内容)/标志寄存器字段/指令指针字段EIP/先前任务链(前一个任务的TSS段选择符)
2)静态字段:
处理器会读取这些字段的内容,但是不会改变他们。这些字段的内容是在任务创建的时候被初始化的。
LDT段选择符
CR3控制寄存器字段
特权级0~2的堆栈指针字段(堆栈选择符SS0~SS2)
调试陷阱T标志字段

IO位图基地址


3.2TSS描述符


它只能放在GDT中,结构如下:


Type中的忙标志B:忙标志被设置,表示任务处于运行或者挂起状态,任务不可递归执行,因此处理器使用B来检测企图对被中断任务的调用。
其他相应字段和一般段描述符相同

使用调用或者跳转指令,任何可以访问TSS描述符的程序都能够造成任务切换,但是可以访问TSS描述符并不代表用户具有修改描述符的能力。如果想要修改它,可以通过映射到内存相同能位置的数据段描述符来实现——别名操作符。将TSS描述符加载进入任何一个段描述符都将产生一个异常。企图使用TI标志置位的描述符(当前LDT中的选择符)来访问TSS段也将导致异常。

3.3任务寄存器


TR存放16b的对于TSS的段选择符(同时不可见部分缓冲着描述符),LTR和STR分别用于加载和保存TR的可见部分,LTR只能被特权级0的程序执行。LTR通常用于系统初始化期间给TR寄存器加载初值。随后,TR的内容会在任务切换的时候改变。

3.4任务门描述符


任务门描述符提供一个对任务间接、受保护的引用,格式如图:


可以存放在GDT、LDT、IDT表中。任务门描述符中的TSS选择字段指向GDT中的一个TSS段描述符。这个TSS选择符的RPL不用,任务门描述符中的DP刘永余在任务切换的时候控制对TSS段的访问。注意,使用任务门的时候,目标TSS段描述符的DPL忽略不用,因为我们用的是任务门描述符的相关字段。程序可以通过任务门描述符或者TSS段描述符来访问一个任务。


4.任务切换


处理器用以下的四种方式来完成任务切换:
1)当前任务对GDT中的TSS描述符执行JMP和CALL指令
2)当前任务对GDT或者LDT中的任务门描述符执行JMP和CALL指令
3)中断或者异常响亮指向IDT表中的任务门描述符
4)当EFLAGS中的NT置位的时候,当前位置执行IRET指令

JMP、CALL、IRET以及中断和异常都是处理器的普通机制,可用于不发生任务切换的环境。对于TSS描述符或者任务门的引用,或者NT标志的状态,确定是否会发生任务切换。IDT中有任务门、陷阱门和中断门,前者才会发生任务切换。

关于中断返回:中断服务过程总是把执行权返回到被中断的过程中,被中断的过程可能在另一个任务中。如果NT标志是复位状态(0),执行一般返回处理;如果NT标志是置位状态返回操作会产生任务切换,切换到的新任务,由中断服务过程TSS中的TSS选择符决定。

任务切换的步骤:

1)从JMP、CALL指令的当前操作数,任务门,当前TSS的前一个任务链字段(IRET引起的任务切换)取得新任务的TSS段选择符
2)检查当前任务是否允许切换到新的任务:jmp和call——CPL、RPL、DPL按照普通数据段访问规则;任务门——无论面目标门或者TSS段描述符的DPL是什么,异常和中断(除了INT n指令产生的中断)和IRET指令都允许任务切换。INT n引起的切换,需要检查DPL。
3)检查新任务的TSS描述符是否标志为存在,并且TSS段长度有效(大于0x67)
4)老任务忙位B:如果任务切换来自JMP和IRET,处理器会把老任务的忙位复位(B=0),表示这个任务已经执行完毕;其他情况,B保持不变。
5)NT标志:如果任务切换来自IRET,NT=0;否则,不改动NT
6)当前任务状态保存到TSS中
7)新任务的NT标志:任务切换来自IRET和JMP,NT不变;其他,NT置位
8)新任务的忙标志B:任务切换来自IRET,B保持不变;其他,B置位
9)用新任务的段选择符和描述符加载到TR,设置CR0的TS标志。
10)将新任务的状态,加载进入处理器
11)开始执行新任务。

执行任务切换时候,新老任务特权级没有任何联系。

5.任务链


TSS的前一任务字段以及EFLAGS中的NT标志用于返回到前一个任务,NT标志指出了当前执行的任务是否嵌套在另外一个任务中执行。

call、中断和陷进都是引发的嵌套任务,表示老的任务还没有结束;jmp引发的是非嵌套任务,意味着老的任务已经结束;IRET用于挂起一个任务,返回到前一个任务。

任务切换引起相关标志变换如下表:(注意,这些命令改变了哪些位)

标志或字段

JMP指令的影响

CALL指令或中断的影响

IRET指令的影响

新任务忙标志B

设置标志。以前须已被清除

设置标志。以前须已被清除

不变。必须已被设置

老任务忙标志B

被清除

不变。当前处于设置状态

设置标志

新任务NT标志

设置成新任务TSS中的值

设置标志

设置成新任务TSS中的值

老任务NT标志

不变

不变

清除标志

新任务链接字段

不变

存放老任务TSS段选择符

不变

老任务链接字段

不变

不变

不变

CR0中TS标志

设置标志

设置标志

设置标志


对比:
新任务的B,基本上都是设置
老任务的B:只有jmp,是清除,表明jmp过后,老任务结束了。
新任务NT:只有call引发的,一定是嵌套
老任务NT:只有IRET是清除,因为这个任务被挂起了,并没有在运行

另外,我们使用忙标志B来防止递归的任务切换:
1)调度一个任务,将新任务置位
2)如果调度任务,当前任务处于嵌套链中,那么它仍然保持置位
3)切换新任务的时候,如果新任务的B置位,那么将产生异常(说明产生了递归);如果任务切换是IRET引起的,那么不会在新任务B=1的时候产生异常——因为IRET是非嵌套的,所以不存在递归任务。

6.任务地址空间


任务地址空间由她能够访问到的段构成。

6.1将任务映射到线性和物理地址空间


1)所有任务共享同样一个线性地址到物理地址的映射——没有开启分页机制,就是如此
2)每个任务都有自己的线性地址空间
对于映射任务线性地址空间的两种方法,所有任务的TSS段都必须存放在可共享的物理地址空间区域中。

6.2映射逻辑地址空间


为了在任务之间共享数据,用下列方法来为数据段建立共享的逻辑到物理地址空间的映射
1)通过GDT段描述符
2)工过共享的LDT
3)通过映射到线性地址空间公共区域的不同LDT的段描述符——别名段。
0 0