调用门详解

说明:此文是我将以前的两篇博文(读书笔记28和29)中的部分内容综合而来,如遇重复,请您自行跳过。

1. 调用门描述符的格式

调用门用于在不同特权级之间实现受控的程序控制转移,通常仅用于使用特权级保护机制的操作系统中。本质上,它只是一个描述符,一个不同于代码段和数据段的描述符,可以安装在GDT或者LGT中,但是不能安装在IDT(中断描述符表)中。
注意:Linux Kernel 0.12 中并没有用到调用门。

为了访问调用门,我们需要为CALL或者JMP指令的操作数提供一个远指针。该指针中的选择子用于指定调用门,而指针中的偏移值虽然需要,但是CPU不会使用它。该偏移值可以设置为任意值。当处理器访问调用门时,它会使用调用门中的段选择子来定位目标代码段的段描述符。然后CPU会把代码段描述符中的基地址和调用门中的偏移值进行组合,形成代码段中指定程序入口点的线性地址。

3. 特权级检查规则

通过调用门进行控制转移时,CPU会检查以下字段:
1. 当前特权级CPL
2. 调用指令中的调用门选择子的RPL
3. 调用门描述符中的DPL
4. 目标代码段描述符中的DPL
5. 目标代码段描述符中的一致性标志C

需要说明的是:如果通过调用门把控制转移到了更高特权级的非一致代码段中,那么CPL就会被设置为目标代码段的DPL值,并且会引起堆栈切换。

4. 堆栈切换

如果通过调用门把控制转移到了更高特权级的非一致代码段中,那么CPL就会被设置为目标代码段的DPL值,并且会引起堆栈切换。为什么要切换堆栈呢有以下几点:
1. 因为栈段的特权级必须同CPL保持一致;
2. 防止高特权级程序由于栈空间不足而崩溃;
3. 防止低特权级程序通过共享的栈有意或无意地干扰高特权级程序。

为了切换栈,每个任务除了自己的固有栈之外,还必须额外定义一套或多套栈,具体是多少取决于任务的特权级别。
0特权级的任务不需要额外的栈,因为除了从调用高特权级的例程(通常是操作系统例程)返回外,不允许将控制从特权级高的代码段转移到特权级低的代码段——操作系统不会引用可靠性比自己低的代码;1特权级的任务需要额外定义一个DPL为0的栈,以便将控制转移到0特权级时使用;2特权级的任务需要额外定义两个栈,其DPL分别为0和1;3特权级的任务最多额外定义三个栈,其DPL分别为0、1、2.

以下文字摘自《Intel Architecture Software Developer’s Manual Volume 3:System Programming》的4.8.5节——Stack Switching.

Each task must define up to 4 stacks: one for applications code (running at privilege level 3) and one for each of the privilege levels 2, 1, and 0 that are used. (If only two privilege levels are used[3 and 0], then only two stacks must be defined.)

操作系统负责为任务用到的所有特权级分配栈空间和创建栈段描述符,并且在任务的TSS中填写栈段的选择子和ESP的初始值(下图是TSS的一部分)。

另外,如果通过调用门的控制转移是指令发起的,结果就是“肉包子打狗——有去无回”,且没有特权级变化,也不需要切换栈。相反,如果是指令发起的,则可以使用远返回指令把控制返回到调用者。

5.2. 返回的过程

对于相同特权级的返回,CPU从堆栈中弹出EIP和CS;会发生特权级改变的远返回仅允许返回到低特权级程序中,即返回到的代码段的DPL在数值上要大于CPL。返回的全部过程如下:

  1. 检测被调用者栈中CS寄存器的RPL字段值,以确定在返回时特权级是否发生改变。
  2. 弹出并使用被调用过程栈上的值加载EIP和CS寄存器。在此过程中会对代码段描述符和代码段选择子的RPL进行特权级与类型检查。
  3. 如果远返回指令是带参数的,则将参数和ESP寄存器的当前值相加,以跳过被调用者栈中的参数部分,最后的结果是ESP寄存器指向调用者SS和ESP的压栈值。注意,指令的参数必须等于调用门中所有参数的总字节数之和。
  4. 如果返回时需要改变特权级,则从栈中将ESP和SS弹出,并把值代入寄存器ESP和SS,切换到调用者的栈。
  5. 如果远返回指令是带参数的,则将参数和ESP寄存器的当前值相加,以跳过调用者栈中的参数部分,最后的结果是调用者的栈恢复平衡。
  6. 如果返回时需要改变特权级,则检查DS,ES,FS和GS的内容,如果段选择子指向数据段或者非一致代码段且段描述符的DPL在数值上小于返回后的新CPL,那么就把数值0传送到该段寄存器。

【end】

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年4月13日
下一篇 2016年4月13日

相关推荐