1、80x86的进程管理与切换描述符表80x86的进程管理与切换、描述符(表)【说明】1、这是网友的资料,本人觉得很好,只是对其稍加整理与补充。整理时间:2012年11月26日20:58:432、这并不是针对具体的操作系统的,这只是80x86 CPU对操作系统进程管理与切换的硬件支持。80386保护模式下的程序需要经常用到如下一些数据结构 选择符(selector)描述符表 (descriptor table)段描述符(segment descriptor)门描述符(gate descriptor)他们之间的关系如下:180386段管理机制80386分段机制需要用到以下数据结构: 段描述符(seg
2、ment descriptor) 段描述符表 (descriptor table)选择符(selector)1.1 段 80386有两种类型的段。存储段是存放可由程序直接进行访问的代码和数据的段。系统段是为了实现存储管理机制所使用的一种特别的段。在80386中,有两种系统段:任务状态段TSS和局部描述符表LDT段。存储段没有特定的格式,存放的是简单的代码或者数据。系统段有特殊的格式,LDT段存放的是局部描述符表,整个段就是一张表,每个表项是8字节的段描述符号。TSS段存放的是任务状态,它有特定的数据结构,下面会有介绍。1.2 段描述符80386的描述符类型一共两种,除了段描述符还有一种是门描述
3、符,门描述符一共四种类型:任务门、中断门、陷阱门和调用门。门描述符和段描述符差别很大,很多字段意义完全不同。80386描述符如下:门描述符后面介绍,本节介绍段描述符。在保护方式下,每一个段都有一个相应的8字节描述符来描述。段描述符中保存了段的所有属性,如段基地址,段限长,段特权级等。程序通过段描述符可以得到段的所有属性。段描述符通用格式如下:1.2.1 存储段描述符 TYPE说明存储段描述符所描述的存储段的具体属性。 其中的位0指示描述符是否被访问过(Accessed),用符号A标记。A=0表示尚未被访问,A=1 表示段已被访问。当把描述符的相应选择子装入到段寄存器时,80386把该位置为1,
4、表明描述符已被访问。操作系统可测试访问位,已确定描述符是否被访问过。 其中的位3指示所描述的段是代码段还是数据段,用符号E标记。E=0表示段为数据段,相应的描述符也就是数据段(包括堆栈段)描述符。数据段是不可执行的,但总是可读的。 E=1表示段是可执行段,即代码段,相应的描述符就是代码段描述符。代码段总是不可写的,若需要对代码段进行写入操作,则必须使用别名技术,即用一个可写的数据段描述符来描述该代码段,然后对此数据段进行写入。 在数据段描述符中(E=0的情况),TYPE中的位1指示所描述的数据段是否可写,用W标记。 W=0表示对应的数据段不可写。反之,W=1表示数据段是可写的。注意,数据段总是
5、可读的。TYPE中的位2是ED位,指示所描述的数据段的扩展方向。ED=0表示数据段向高端扩展,也即段内偏移必须小于等于段界限。ED=1表示数据段向低扩展,段内偏移必须大于段界限。 在代码段描述符中(E=1的情况),TYPE中的位1指示所描述的代码段是否可读,用符号R标记。R=0表示对应的代码段不可读,只能执行。R=1表示对应的代码段可读可执行。注意代码段总是不可写的,若需要对代码段进行写入操作,则必须使用别名技术。在代码段中,TYPE中的位2指示所描述的代码段是否是一致代码段,用C标记。C=0表示对应的代码段不是一致代码段(普通代码段),C=1表示对应的代码段是一致代码段。 存储段描述符中的T
6、YPE字段所说明的属性可归纳为下表: 1.2.2 系统段描述符 存储段描述符和系统段描述符差别很小,图中红色的地方是两者的差别之处。系统段描述符中的段基地址和段界限字段与存储段描述符中的意义完全相同;属性中的G位、AVL位、P位和DPL字段的作用也完全相同。存储段描述符属性中的D位在系统段描述符中不使用,现用符号X表示。系统段描述符的类型字段TYPE仍是4位,其编码及表示的类型列于下表,其含义与存储段描述符的类型却完全不同。从上表可见,只有类型编码为2、1、3、9和B的描述符才是真正的系统段描述符,它们用于描述系统段LDT和任务状态段TSS,其它类型的描述符是门描述符。 1.3 段描述符表描述
7、符都放在描述符表中。在80386中有三种类型的描述符表:全局描述符表GDT(Global Descriptor Table)、局部描述符表LDT(Local Descriptor Table)和中断描述符表IDT(Interrupt Descriptor Table)。在整个系统中,全局描述符表GDT和中断描述符表IDT是唯一的,局部描述符表可以有若干张,每个任务可以有一张。这三种描述符表都存储在内存中。 全局描述符表GDT含有描述操作系统所使用的代码段、数据段和堆栈段的描述符,系统段描述符。在任务切换时,并不切换GDT。系统段描述符只能放在GDT中,不能放在LDT中。 每个任务的局部描述符表
8、LDT含有该任务自己的代码段、数据段和堆栈段的描述符,也包含该任务所使用的一些门描述符,如任务门和调用门描述符等。随着任务的切换,系统当前的局部描述符表LDT也随之切换。局部描述符表LDT其实是一个系统段,与之对应的描述符是LDT段描述符,它只能存放在GDT中。 IDT(中断描述符表)后面介绍。 CPU中有3个特殊的寄存器,GDTR、LDTR和IDTR,它们分别对应GDT,当前LDT和IDT,系统通过这三个寄存器来定位相应的描述符表。 GDTR一共46位,高32位以线性地址方式存放GDT的基地址,低16位存放GDT表限长。所以GDT最大长度为64KB。由于一个描述符占8字节,所以最多有8192
9、个表项。但是第0个表项是不用的,所以最多存放8191个描述符。 IDTR:也是48位寄存器,高32位存放中断描述符表LDT的 32 位线性首地址,低16位IDT表的限长。虽然和GDT一样,IDT最多可以有8192个表项,但是由于80386只识别256个中断向量号,所以IDT最大长度是2K。 LDTR比较特殊,包括16位可见部分和48位不可见部分。16位可见部分存放GDT中对应的LDT段的选择符,48位不可见部分作为高速缓冲,存放LDT的32位线性首地址和16位限长。一个LDT的长度最大也是64KB。第0个表项也是不用的。 GDT、LDT、GDTR以及LDTR的关系如下图:1.4 段选择符 段描
10、述符表(GDT、LDT)是通过选择符来索引的,IDT不用通过选择符,直接用中断号索引。 保护模式下段寄存器存放的都是段选择符。 选择符一共16位,格式如下: Index一共13位,正好可以索引到GDT或者LDT的最大限长。由于描述符表都是8直接对齐的,所以吧index放在高13位,这样把低3位屏蔽后就可以得到表内 偏移地址。 TI(Table Indicator)位是引用描述符表指示位,TI=0指示从全局描述符表GDT中读取描述符;TI=1指示从局部描述符表LDT中读取描述符。 选择子的最低两位是请求特权级RPL(Requested Privilege Level),用于特权检查。CS和SS寄
11、存器中的RPL就是CPL(current privilege level当前特权级)。1.5 段寄存器80386的段寄存器都包含有一个16位可见部分和一个不可见部分。段寄存器的可见部分由程序来操作,就好像是简单的16位寄存器,存放16位的段选择符。不可见部分由CPU维护,作为高速缓冲。每当段选择符被加载到段寄存器中时,CPU取得段描述符表中相应的描述符,然后把段的属性放入不可见部分中。比如段基地址,限长,以及其他属性。这样避免每次访问内存。1.6 段变换 段选择符中TI位为0时的情况,这时从GDT中读取段描述符段选择符中TI位为1时的情况,这时从LDT中读取段描述符。需要先从GDT中读取LDT
12、段描述符,然后再从LDT中读取段基地址。(所以系统要先预设GDTR和LDTR的地址)2多任务 上面介绍了存储段和LDT段,这里介绍另外一个系统段任务状态段TSS。 为了提供多任务,80386使用了特殊的数据结构,主要有任务状态段TSS(Task State Segment)和任务寄存器TR。2.1 任务状态段 一个任务的所有信息都存放在任务状态段中,任务状态段与相应的段描述符相关。任务段描述符只能存放在GDT中,TR寄存器16位可见部分存放TSS段选择符。在任务切换过程中,首先,处理器中各寄存器的当前值被自动保存到TR所指定的TSS中;然后,下一任务的TSS的选择子被装入TR;最后,从TR所指
13、定的TSS中取出各寄存器的值送到处理器的各寄存器中。由此可见,通过在TSS中保存任务现场各寄存器状态的完整映象,实现任务的切换。从图中可见,TSS的基本格式由104(0x64)字节组成。这104字节的基本格式是不可改变的,但在此之外系统软件还可定义若干附加信息。基本的104字节可分为链接字段区域、内层堆栈指针区域、地址映射寄存器区域、寄存器保存区域和其它字段等五个区域。 寄存器保存区域寄存器保存区域位于TSS内偏移32至95处,用于保存通用寄存器、段寄存器、指令指针和标志寄存器。当TSS对应的任务正在执行时,保存区域是未定义的;在当前任务被切换出时,这些寄存器的当前值就保存在该区域。当下次切换
14、回原任务时,再从保存区域恢复出这些寄存器的值,从而,使处理器恢复成该任务换出前的状态,最终使任务能够恢复执行内层堆栈指针区域为了有效地实现保护,同一个任务在不同的特权级下使用不同的堆栈。所以,一个任务可能具有四个堆栈,对应四个特权级。四个堆栈需要四个堆栈指针。TSS的内层堆栈指针区域中有三个堆栈指针,它们都是48位的全指针(16位的选择子和32位的偏移),分别指向0级、1级和2级堆栈的栈顶,依次存放在TSS中偏移为4、12及20开始的位置。当发生向内层转移时,把适当的堆栈指针装入SS及ESP寄存器以变换到内层堆栈,外层堆栈的指针保存在内层堆栈中。没有指向3级堆栈的指针,因为3级是最外层,所以任
15、何一个向内层的转移都不可能转移到3级。但是,当特权级由内层向外层变换时,并不把内层堆栈的指针保存到TSS的内层堆栈指针区域地址映射寄存器区域从虚拟地址空间到线性地址空间的映射由GDT和LDT确定,与特定任务相关的部分由LDT确定,而LDT又由LDTR确定。如果采用分页机制,那么由线性地址空间到物理地址空间的映射由包含页目录表起始物理地址的控制寄存器CR3确定。所以,与特定任务相关的虚拟地址空间到物理地址空间的映射由LDTR和CR3确定。显然,随着任务的切换,地址映射关系也要切换。 TSS的地址映射寄存器区域由位于偏移28处的双字字段(CR3)和位于偏移96处的字段(LDTR)组成。在任务切换时
16、,处理器自动从要执行任务的TSS中取出这两个字段,分别装入到寄存器CR3和LDTR。这样就改变了虚拟地址空间到物理地址空间的映射。 但是,在任务切换时,处理器并不把换出任务的寄存器CR3和LDTR的内容保存到TSS中的地址映射寄存器区域。事实上,处理器也从来不向该区域自动写入。因此,如果程序改变了LDTR或CR3,那么必须把新值人为地保存到TSS中的地址映射寄存器区域相应字段中。可以通过别名技术实现此功能。 链接字段链接字段安排在TSS内偏移0开始的双字中,其高16位未用。在起链接作用时,地16位保存前一任务的TSS描述符的选择子。 如果当前的任务由段间调用指令CALL或中断/异常而激活,那么
17、链接字段保存被挂起任务的 TSS的选择子,并且标志寄存器EFLAGS中的NT位被置1,使链接字段有效。在返回时,由于NT标志位为1,返回指令RET或中断返回指令IRET将使得控制沿链接字段所指恢复到链上的前一个任务。 其它字段为了实现输入/输出保护,要使用I/O许可位图。任务使用的I/O许可位图也存放在TSS中,作为TSS的扩展部分。在TSS内偏移102处的字用于存放I/O许可位图在TSS内的偏移(从TSS开头开始计算)。关于I/O许可位图的作用,以后的文章中将会详细介绍。 在TSS内偏移100处的字是为任务提供的特别属性。在80386中,只定义了一种属性,即调试陷阱。该属性是字的最低位,用T
18、表示。该字的其它位置被保留,必须被置为0。在发生任务切换时,如果进入任务的T位为1,那么在任务切换完成之后,新任务的第一条指令执行之前产生调试陷阱。 2.2 任务寄存器任务寄存器TR也是由可见和不可见两个部分所组成。其中16位的可见部分用来存放TSS段选择符,它指向GDT中的一个TSS描述符。处理器使用TR中的不可见部分来高速缓存TSS的段描述符,包括TSS段的基地址和段长度。2.3 任务门任务门描述符格式如下:一个任务门描述符正像一个门为一个任务的执行提供控制和保护。任务门描述符可以位于GDT、LDT或IDT中。2.4 任务切换2.4.1任务切换的四种形式处理器可以通过下列四种形式之一切换到
19、其他任务执行:在当前程序、任务或过程中执行一条JMP或CALL指令转到GDT中TSS描述符。(直接任务转换) 在当前程序、任务或过程中执行一条JMP或CALL指令转到GDT或当前LDT中一个任务门描述符。(间接任务转换)通过一个中断或异常矢量指向IDT中的一个任务门描述符。(间接任务转换)当标志位EFLAGSNT设置时,当前任务执行指令IRET(或IRETD,用于32位程序转换。(直接任务转换) 2.4.2任务切换步骤当处理器切换到一个新任务时,执行下列操作步骤:从一个任务门或先前任务的连接域(反向链)中(由指令IRET启动任务切换)、从指令JMP或CALL的操作数为新任务获取TSS段选择子。
20、 检查当前的任务是否允许转向新任务,访问权限规则适用于指令JMP和CALL,当前任务的CPL阈值和新任务段选择子的RPL阈值必须小于或等于TSS描述符的DPL域值或所参考任务门的DPL域值。即直接任务转换要求:DPLTSS描述符MAX(CPL现行特权,RPL新任务的段选择子)间接任务转换要求:DPL任务门MAX(CPL现行特权,RPL指向任务门的选择子)除了由指令INT n引起的软件中断之外凡是异常或中断以及指令IRET允许切换到新任务,均无需考虑目的任务门或TSS描述符的DPL,对于由指令INT n引起的中断,则要检查其DPL。检查新任务的TSS描述符是否存在,以及是否有一个合法的界限(大于
21、或等于 67H)。 检查新任务是否有效(调用、跳转、异常或中断)和是否忙(IRET返回)。检查当前任务的TSS。新任务的TSS和任务切换中所使用的所有段描述符是否被分页进入系统存储器。如果任务切换是由指令JMP或IRET引起,处理器则清除当前任务TSS描述符中的忙标志位B,如果由指令CALL、一次异常或一次中断所引起,设置忙标志位B。如果任务切换是由指令IRET引起,处理器则清除临时保存的EFLAGS寄存器副本中的标志位NT,如果由指令CALL或JMP、一次异常或一次中断所引起,临时保存的EFLAGS寄存器副本中的标志位NT不变。在当前任务的TSS中保存当前任务的状态,处理器根据TR内容寻址当
22、前TSS的基地址,复制下列寄存器的状态到当前任务的TSS中;所有通用目的寄存器、保存在段寄存器中的段选择符、关于EFLAGS寄存器的临时存储副本、以及指令指针EIP。 此时必须注意的是:如果所有的检查和保存都成功执行,处理器允许任务切换,如果在从第1步到第8步的过程中发生了一个不可恢复的错误,处理器将不能完成任务间的切换,并强迫处理器返回到启动任务切换指令执行之前的状态,如果这种错误发生在任务切换允许之后(即在第9步到第14步),处理器完成任务切换,而不执行其他的访问和段的有效性检查,并在开始执行新任务之前产生一个适当的异常。如果在允许之后发生了异常,异常句柄必须在允许处理器执行任务之前,自身
23、完成任务切换。如果任务切换是由执行CALL指令、一次异常或一次中断所引起,处理器将当前TSS的段选择子复制到新任务TSS的反向链中。临时保存在新任务TSS中EFLAGS寄存器副本的标志位NT被处理器设置;如果由指令IRET所引起,处理器恢复临时保存在堆栈中EFLAGS寄存器副本的标志位NT;如果由指令JMP所引起,标志位NT不变。如果任务切换是由指令CALL、指令JMP、一次异常或一次中断所引起,处理器则设置新任务TSS描述符中的忙标志位B;如果由指令IRET所引起,忙标志位B被处理器清除。 设置新任务TSS中的副本标志位CR0TS。为TR装载新任务TSS所需要的段选择子和描述符。从新任务的T
24、SS中装载新任务的状态到处理器中,在该步中可能发生任何与装载和校验段描述符相关的错误,被装载的任务状态信息包含在LDTR、PDRB(即CR3)、EFLAGS。 EIP、通用目的寄存器和段寄存器。开始执行新任务。对于一个异常句柄,新任务的第一条指令不执行。 当任务成功切换时,当前执行任务的状态总被保存。如果该任务被恢复执行,执行使从所保存EIP值指向的指令处开始,寄存器的值也被恢复到任务挂起时的保存值,这与中断现场的恢复类似。当发生任务切换时,新任务的特权级并不继承前任挂起任务的特权级,新任务按CS寄存器的CPL域指定的特权级开始执行, CS从TSS中装载得到。通过各自独立的地址空间、 不同的T
25、SS和访问权限可以对任务进行很好的隔离,在任务切换时软件并不需要执行对特权级的直接检查。2.4.3一个任务的运行环境 一个任务的运行环境由寄存器组和地址空间组成。寄存器组中保存的是任务当前的状态。地址空间由若干个段构成,每个段都有相应的段描述符,这些描述符要么放在GDT中,为所有任务共享,要么放在LDT中,是任务的私有空间。 任务的段包括: GDT中索引的代码段,数据段,一般这是操作系统的内核数据段代码段。 LDT段,就是一张局部描述符表,由该表再索引其他私有段,比如私有数据段,私有代码等。 TSS段,保存有该任务的所有信息,任务切换用。3中断与异常处理3.1 中断描述符表(IDT) 中断描述
26、符表IDT(Interrupt Descriptor Table)将每个异常或中断向量分别与它们的处理过程秩系起来。与GDT和LDT表类似,IDT也是由8字节长描述符组成的一个数组。与GDT不同的是,表中第1项可以包含描述符。为了构成IDT表中的一个索引值,处理器把异常或中断的向量号*8。因为最多只有256个中断或异常向量,所以IDT无需包含多于256个描述符。IDT中可以含有少于256个描述符,因为只有可能发生的异常或中断才需要描述符。不过IDT中所有空描述符项应该设置其存在位(标志)为0。3.2 IDT描述符 IDT表中可以存放三种类型的门描述符: 中断门(Interrupt gate)描
27、述符 陷阱门( Trap gate)描述符 任务门( Task gate)描述符任务门已在第2节-多任务里介绍过了。这里只给出中断门和陷阱门的描述符。中断门描述符:陷阱门描述符:3.3 中断和异常处理当响应一个异常或中断时,处理器使用异常或中断的向量作为IDT表中的索引。如果索引值指向中断门或陷阱门,则处理器使用与CALL指令操作调用门类似的方法调用异常或中断处理过程。如果索引值指向任务门,则处理器使用与CALL指令操作任务门类似的方法进行任务切换,执行异常或中断的处理任务。3.3.1 不进行任务切换的处理过程异常和中断向量若指向中断门或陷阱门,则执行不进行任务切换的中断过程。异常或中断门引用
28、运行在当前任务上下文中的异常或中断处理过程,如下图:3.3.2 进行任务切换的 异常和中断向量若指向任务门,则进行任务切换,执行中断任务。中断处理任务切换如下图:4. 对描述符(表)的补充和总结4.1 对门描述符的补充调用门 调用门用于在不同特权级之间实现受控的程序控制转移。通常仅用于使用特权级保护机制的操作系统中。调用门描述符可以存放在GDT或LDT中,但不能放在IDT中。调用门描述符格式如下:4.2 对描述符(表)的总结 门描述符:(1)调用门描述符只能在GDT或LDT中,不能放在IDT中;(2)中断门描述符和陷阱门描述符在IDT中;(3)任务门描述符可以在GDT、LDT、IDT中(4)Linux-0.11中用了特权级0的中断门、特权级0的陷阱门和特权级3的陷阱门。描述符表:(1)IDT中只有中断门描述符、陷阱门描述符或任务门描述符;(2)GDT中可以有存储段描述符(数据段描述符、代码段描述符)、系统段描述符(LDT描述符、TSS描述符)、调用门描述符或任务门描述符;(3)LDT中可以有任务自己的代码段描述符、数据段描述符、堆栈段描述符、任务门描述符或调用门描述符若有问题,欢迎联系:*
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1