学习笔记--特权级代码段之间的转移(一)

一、对于“特权级”这个词,你可能任然感到一些陌生,但如果提起DPL,RPL,你应该还是有印象吧,实际上,DPL所代表的Descriptor Privilege Level以及RPL所代表的Request Privilege Level都是用来表示特权级别的。只不过,前面所有的例子都是运行在最高特权级下,所以涉及到的DPL和RPL都是0(最高特权级别)。

在IA32的分页机制中特权级别总共有4个特权级别,从高到低分别是0,1,2,3。数字越小表示的特权级越大。特权级如下图所示:


为核心的代码和数据,将被存放在特权级较高的层级中。处理器将用这样的机制来避免低特权级的任务在不被允许的情况下访问位于高特权级的段。

不知大家还记得否,在前面代码中,我们涉及到一致代码段和非一致代码段但是并没有解释,留到后面来解释,今天在这里就必须要好好说一下了。

二、一致代码段 和 非一致代码段
系统要安全,必须保证内核与用户程序分离开,内核要安全,必须不能被用户来打扰。但是有的时候,用户程序也是需要访问内核中的部分数据,那怎么办?

于是操作系统就将内核中的段分为共享的代码段和非共享的代码段两部分。
其中一致代码段就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接访问的代码。
一致代码段的限制作用:
(1)特权级高的代码段不允许访问特权级低的代码段:即内核态不允许调用用户态下的代码。
(2)特权级低的代码段可以访问特权级高的代码段,但是当前的特权级不发生变化。即:用户态可以访问内核态的代码,但是用户态仍然是用户态。

非一致代码段:为了避免低特权级的访问而被操作系统保护起来的系统代码,也就是非共享代码。
非一致代码段的限制作用
(1)只允许同特权级间访问
(2)绝对禁止不同级间访问,即:用户态不能访问内核态,内核态也不访问用户态。

下图为一致码段与非一致码段的访问规则:


三、CPL、DPL、RPL分别代表的含义,存储在什么位置,以及它们之间的关系
1、CPL(Current Privilege Level)是当前执行的程序或任务的特权级。它被存储在CS和SS的第0位和第1位上。通常情况下,CPL等于代码的段的特权级。在遇到一致代码段时,一致代码段可以被相同或者更低特权级的代码访问。当处理器访问一个与CPL特权级不同的一致代码段时,CPL不会被改变。

2、DPL(Descriptor Privilege Level):DPL表示段或者门的特权级,它被存储在段描述符或者门描述符的DPL字段中。当当前代码段试图访问一个段或者门时,DPL将会和CPL以及段或门选择子的RPL相比较,根据段或者门类型的不同,DPL将会被区别对待,下面介绍一下各种类型的段或者门的情况。
(1)数据段:DPL规定了可以访问此段的最低特权级。比如,一个数据段的DPL是1,那么只有运行在CPL为0或者1的程序才有权访问它。
(2)非一致代码段(不使用调用门的情况下):DPL规定访问此段的特权级。比如一个非一致代码段的特权级为0,那么只有CPL为0的程序才可以访问它。
(3)调用门:DPL规定了当前执行的程序或任务可以访问此调用门的最低特权级(这与数据段的规则是一致的)。
(4)一致代码段和通过调用门访问的非一致代码段:DPL规定了访问此段的最高特权级。比如,一个一致代码段的DPL是2,那么CPL为0和1的程序将无法访问此段。

(5)TSS:DPL规定了当前执行的程序或任务可以访问此调用门的最低特权级(这与数据段的规则一致)

3、RPL(Requested Privilege Level):RPL是通过选择子的第0位和第1位表现出来的。处理器通过检查RPL和CPL来确认一个访问请求是否合法。即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的,也就是说,如果RPL的数字比CPL大(数字越大特权级越低),那么RPL将会起决定性作用,反之亦然。(RPL说明的是进程对段访问的请求权限(Request Privilege Level),是对于段选择子而言的,每个段选择子有自己的 RPL,它说明的是进程对段访问的请求权限,有点像函数参数。而且RPL对每个段来说不是固定的,两次访问同一段时的RPL可以不同。RPL可能会削弱 CPL的作用,例如当前CPL=0的进程要访问一个数据段,它把段选择符中的RPL设为3,这样虽然它对该段仍然只有特权为3的访问权限。)

操作系统往往用RPL来避免低特权级应用程序访问高特权级段内的数据。当操作系统过程(被调用过程)从一个应用程序(调用过程)接收到一个选择子时,将会把选择子的RPL设成调用者的特权级。于是,当操作系统用这个选择子去访问相应的段时,处理器将会把调用过程的特权级(已被存到RPL中),而不是更高的操作系统过程的特权级(CPL)进行特权检验。这样,RPL就保证了操作系统不会越俎代庖地代表一个程序去访问一个段,除非这个程序本身是有权限的。

四、不同特权级数据段之间的访问规则

程序从一个代码段转移到另一个代码段之前,目标代码段的选择子会被加载到cs中。作为加载过程的一部分,处理器将会检查描述符的界限、类型、特权级等内容。如果检验成功,cs将被加载,程序控制将转移到新的代码段中,从eip指示的位置开始执行。程序控制转移的发生,可以由指令jmp、call、ret、sysenter、sysexit、int n或iret引起,也可以由中断和异常机制引起。

数据段中DPL规定了可以访问此段的最低特权级,因此,对数据的访问,只要CPL和RPL都小于被访问的数据段的DPL就可以了,即CPL<=DPL和RPL<=DPL。

五、不同特权级代码段之间的转移
使用jmp或call指令可以实现下列4种转移
(1)目标操作数包含目标代码段的段选择子。
(2)目标操作数指向一个包含目标代码段选择子的调用门描述符。
(3)目标操作数指向一个包含目标代码段选择子的TSS。
(4)目标操作数指向一个任务门,这个任务门指向一个包含目标代码段选择子的TSS。
这4种方式可以看做是两大类,一类是通过jmp和call的直接转移(上述第一种),另一类是通过某个描述 
符的间接转移(上述第2,3,4种)。

5.1特权级转移

1、通过jmp或call进行直接转移


从上面可以看出通过jmp和call所能进行的代码段间转移是非常有限的,对于非一致代码段,只能在相同特权级代码段之间转移。遇到一致代码段也最多能从低到高,而且CPL不会改变。如果想自由得进行不同特权级之间的转移,显然需要其它几种方式,即运用门描述符或者TSS.

六、任务状态段和控制门

每个任务有一个任务状态段 TSS,用于保存任务的有关信息,在任务内变换特权级和任务切换时,要用到这些信息。为了控制任务

内发生特权级变换的转移,为了控制任务切换,一般要通过控制门进行这些转移。本文将介绍任务状态段和控制门。                                                                                                                                      

<一>系统段描述符
系统段是为了实现存储管理机制所使用的一种特别的段。在 80386 中,有两种系统段:任务状态段 TSS 和局部描述符表 LDT 段。

用于描述系统段的描述符称为系统段描述符。                                                                                                                                                                                                  

1.系统段描述符的格式系统段描述符的一般格式如下表所示。 



与存储段描述符相比,它们很相似,区分的标志是属性字节中的描述符类型位 DT 的值。DT=1 表示存储段,DT=0 表示系统段。系统段描述符中的段基地址和段界限字段与存储段描述符中的意义完全相同;属性中的 G 位、AVL 位、P 位和 DPL 字段的作用也完全相同。存储段描述符属性中的 D 位在系统段描述符中不使用,现用符号 X 表示。系统段描述符的类型字段 TYPE 仍是 4 位,其编码及表示的类型列于下表,其含义与存储段描述符的类型却完全不同。 


从上表可见,只有类型编码为 2、1、3、9 和 B 的描述符才是真正的系统段描述符,它们用于描述系统段 LDT 和任务状态段 TSS,其它类型的描述符是门描述符。

利用前文定义的存储段描述符结构类型 DESC 仍能方便地在程序中说明系统段描述符。需要注意的是,系统段描述符的选择子不能用来读写系统段,要想读写系统段,必须使用别名技术。

2.LDT 段描述符

LDT 段描述符描述任务的局部描述符表段。例如:下面的描述符 LDTABLE 描述一个局部描述符表段,基地址是 654321H,以字节为单位的界限是 1FH,描述符特权级是 0。

LDTABLE DESC <1FH,4321H,65H,82H,,>
LDT 段描述符必须安排在全局描述符表中才有效。在装载 LDTR 寄存器时,描述符中的 LDT 段基地址和段界限等信息被装入 LDT

段描述符高速缓冲寄存器中。                                                                                           

3.任务状态段描述符

任务状态段 TSS 用于保存任务的各种状态信息。任务状态段描述符描述某个任务状态段 TSS 描述符分为 286TSS 和 386TSS 两类。TSS 描述符规定了任务状态段的基地址和任务状态段的大小等信息。例如,下面的描述符 TempTask 描述一个可用的 386 任务状态段,基地址是 123456H,以字节为单位的界限是 104,描述符特权级是 0。

TempTask DESC <104,3456H,12H,89H,,>

在装载任务状态段寄存器 TR 时,描述符中的段基地址和段界限等信息被装入到 TR 的高速缓冲寄存器中。在任务切换或执行 LTR指令时,要装载 TR 寄存器。

TSS 描述符中的类型规定:TSS 要么为“忙”,要么为“可用”。如果一个任务是当前正执行的任务,或者是用 TSS 中的链接字段沿挂起任务链接到当前任务上的任务,那么该任务是“忙”的任务;否则该任务为“可用”任务。

利用段间转移指令 JMP 和段间调用指令 CALL,直接通过 TSS 描述符或通过任务门可实现任务切换(

在同一任务内,实现特权级从外层到内层变换的普通途径是使用段间调用指令 CALL,通过调用门进行转移;实现特权级从内层向外层变换的普通途径是使用段间返回指令 RET。注意,不能用 JMP 指令实现任务内不同特权级的变换。 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值