一、任务
任务是处理器可以分配调度、执行和挂起的一个工作单元。它可用于执行程序、任务或进程、操作系统服务、中断或异常处理过程和内核代码。
80x86提供了一种机制,这种机制可以用来保护任务的状态、分配任务执行以及从一个任务切换到另一个任务。当工作在保护模式下,处理器所有运行都在任务中。即使是简单系统也必须定义一个任务,更为复杂的系统可以使用处理器的任务管理功能来支持多任务应用。
80x86提供了多任务的硬件支持,任务是一个正在运行的程序,或者是一个等待准备运行的程序。通过中断、异常、 跳转或调用,我们可以执行一个任务。当这些控制形式和某个描述符表中指定项的内容一起使用时,这个描述就是使新任务开始执行的描述符。描述符表中与任务相关的描述符有两类:任务状态段描述符和任务门。当执行权限传给任何这一类描述符石,都会造成任务切换。
任务切换很像过程调用,但任务切换回保存更多的处理器状态信息。任务切换会把控制权完全转移到一个新的执行环境,即新任务的执行环境。这种转移操作要求保存处理器中几乎所有寄存器的当前内容,包括标志寄存器EFLAG和所有的段寄存器。与过程不同,任务不可重入。任务切换不会把任何信息压入栈中,处理器的状态信息都被保存在内存中称为任务状态段的数据结构中。
二、任务的结构和状态
一个任务由两部分组成:任务执行空间
和任务状态段TSS(Task-state segment)
。 任务执行空间包括代码段、堆栈段和一个或多个数据段,如果操作系统使用了处理器的特权级保护机制,那么任务执行空间还需要为每一个特权级提供一个独立的堆栈空间,如图1所示。任务状态段指定了构成任务执行空间的各个段,,并且为人物状态信息提供存储空间。在多任务环境中,任务状态段也为任务之间的链接提供了处理方法
一个任务使用指向其TSS的段选择符来指定。当一个任务被加载进处理器中执行时,那么该任务的段选择符、段基址、段限长以及TSS段描述符属性会被加载进任务寄存器TR(Task Register)中。如果使用了分页机制,那么任务使用的页目录表基地址就会被加载进控制寄存器CR3中。当前执行任务的状态由处理器中胰腺癌所有内容组成:
- 所有通用寄存器和段寄存器信息;
- 标志寄存器EFLAGS、程序指针EIP、控制寄存器CR3、任务寄存器和LDTR寄存器;
- 段寄存器指定的任务当前执行空间;
- I/O映射位图基地址和I/O位图信息(在TSS中);
- 特权级0、1和2的堆栈指针(在TSS中);
- 链接至前一个任务的链指针(在TSS中);
三、任务的执行
软件或处理器可以使用以下方法之一来调度执行一个任务:
-
使用CALL指令明确地调用一个任务;
-
使用JMP指令明确地跳转到一个任务(Linux内核使用的方式);
-
(处理器)隐含第调用一个中断句柄处理任务;
-
隐含第调用一个异常句柄处理任务;
所有这些调度任务执行方法都会使用一个指向任务门或任务TSS段的选择符来确定一个任务。当使用CALL或JMP指令调度一个任务时,指令中的选择符既可以直接选择任务的TSS,也可以选择存放有TSS选择符的任务门。当调度一个任务来处理一个中断或异常时,那么 IDT 中该中断或异常表项必须是一个任务门,并且其中含有终端或异常处理任务的TSS选择符。
当调度一个任务执行时,当前正在运行任务和调度任务之前会自动地发生任务切换操作。在任务切换期间,当前运行任务的执行环境(称为任务的状态或上下文)会被保存到它的TSS中并且暂停该任务的执行。此后新调度任务的上下文会被加载进处理器中,并且从加载的EIP指向的指令处开始执行新任务。
如果当前执行任务(调用者)调用了被调度的新任务(被调用者),那么调用者的TSS段选择符会被保存在被调用者的TSS中,从而提供了一个返回调用者的链接。对于所有的80X86处理器,任务是不可递归调用的,即任务不能调用或跳转到自己。
中断或异常可以通过切换到一个任务来进行处理。在这种情况下,处理器不仅能够执行任务切换来处理中断或异常,而且也会在中断或异常处理任务返回时自动地切换回被中断的任务中去。这种操作方式可以处理在中断任务执行时发生的中断。
作为任务切换操作的一部分,处理器也会切换到另一个LDT,从而允许每个任务基于LDT的段具有不同逻辑到物理地址的映射。同时,页目录寄存器CR3也会在切换时被重新加载,因此每个任务可以有自己的一套页表。这些保护措施能够用来隔离各个任务并且防止防止他们呢相互干扰。