DIY操作系统(6):特权级CPL、DPL与RPL

参考

CPL RPL与DPL 之间的区别和联系

特权级

TSS

Task State Segment,任务状态段,本质是一种用于存储任务运行环境的数据结构,是处理器在硬件上原生支持多任务的一种实现方式。任务分为用户部分和内核部分,加起来才是能让处理器完整运行的程序

TSS可唯一标识一个任务,32位系统下TSS的最小尺寸为104B,结构如下图。
请添加图片描述
处理任务时可能需要进行特权级切换,其本质是处理器的当前特权级在切换,而切换前后应该用不同的栈,否则会使栈中的数据混乱。一共四个特权级,故一个任务最多有四个栈,而TSS中只指示了三个栈,如SS0表示0级栈的段选择子,ESP0表示0级栈的偏移量,这和特权级切换有关。

特权级切换

  1. 由低到高:由中断门、调用门等手段实现,切换时处理器自动地从TSS中找到对应的高特权栈的地址,因此TSS中不需要记录3特权级的栈,因为它是最低的,不可能有从低到高的切换。按照此种思想,可知3特权级的程序拥有3 2 1 0 四个栈,2特权级的程序拥有2 1 0三个栈…
  2. 由高到低:要明白的是,只有由低到高的切换发生后,才会发生由高到低的切换。当由低到高切换时(以3到0为例),处理器会自动把3特权级的段选择子和偏移量压入0特权级的栈中,返回时从栈中即可获得,不需要TSS参与。

CPL、DPL与RPL

段选择子的结构如下。
在这里插入图片描述

  • DPL(Descriptor Privilege Level):存储在段描述符中,每个段的DPL固定,描述了访问该段需要何种特权级。
  • CPL(Current ~):进程运行时,存储在代码段寄存器CS(而非其他段寄存器)的低两位(即RPL)中,描述了当前进程的特权级。
  • RPL(Request ~):CPU中有多个段寄存器,每个段寄存器中的选择子中都有RPL字段,在任意时刻,CS.RPL = CPL。RPL代表资源真正访问者的CPL。
    在这里插入图片描述

请添加图片描述

由实模式切换到保护模式后,CPL为0。

一致性代码段

也称为依从代码段,用于实现低特权级的代码向高特权级代码的转移。规则为:max(CPL, RPL) >= 一致性代码段的DPL则可转移,且转移后,不会把CPL更新为一致性代码段的DPL。

这种转移本身并没有提升特权级,而只是允许执行特权级更高的代码段(并不是随意执行高特权指令),所以相对来说更安全。

访问资源

以下均为不通过调用门直接访问资源的情况:
受访者为代码段时 :

  • 如果目标为非一致性代码段(受到隔离的代码,只能在同一级别间相互访问)
    要求:数值上 CPL=RPL=目标代码段 DPL
  • 如果目标为一致性代码段(不受到隔离,允许被同等级或低等级代码调用)
    要求:数值上CPL >= 目标代码段 DPL && RPL >= 目标代码段 DPL
  • 有关代码的特权检查都发生在能够改变代码段寄存器CS和指令指针寄存器 EIP 的指令中,即这些指令要么改变 EIP,要么改变CS和 EIP。例如 call、 jmp, int、 ret、 sysexit 等能改变程序执行流的指令。

受访者为数据段时:

  • 数值上CPL <= 目标数据段DPL && RPL <= 目标数据段 DPL
  • 特权级检查会发生在往数据段寄存器中加载段选择子的时候,数据段寄存器包括 DS和附加段寄存器ES、 FS、 GS。

受访者为栈段时:

  • 栈段的特权级检查比较特殊,因为在各个特权级下,处理器都要有相应的栈,往段寄存器 SS 中赋予数据段选择子时,处理器要求 CPL 等于栈段选择子对应的数据段的 DPL,即数值上 CPL=RPL =用作栈的目标数据段 DPL。

门描述符 基础

门结构是一种描述符,记录着一段特殊程序的起始地址,这段程序可以实现特权级由低到高的切换。

门结构有任务门、中断门、调用门、陷阱门四种

门描述符与段描述符的区别在于:段描述符对应的是一片内存区域,而门描述符中除了任务门外,其他三种门都对应了一段特殊程序。

联系在于:任何程序都属于某个内存段,所以程序的地址需要用代码段选择子+段内偏移来描述,门描述符(除了任务门外)是基于段描述符的,任务门有点特殊,它用任务 TSS 的描述符选择子来描述一个任务。

下图为中断门描述符格式,最核心的是代码段描述符选择子和中断程序的段内偏移。

在这里插入图片描述

位置调用方式
任务门GDT、LDT、IDTcall、jmp指令
调用门GDT、LDTcall、jmp指令
中断门IDT中断信号
陷阱门IDT中断信号

各种门描述符的使用如下
在这里插入图片描述
作用:
请添加图片描述

要使用门的功能,至少需要满足两个条件:

  • CPL <= 门的DPL。这样才能对门进行调用。
  • CPL >= 目标代码段DPL。这样才满足由低到高提升特权级的原则。

调用门

调用门描述符的结构如下:
请添加图片描述
call 调用门选择子指令的执行流程如下(不涉及分页机制,门描述符存在GDT中):

请添加图片描述

  1. 内核例程需要参数,所以需要实现ring3程序向ring0程序的传参。参数最初是由用户程序以压入用户栈的形式提交给调用门的,为了进行“越权”的参数传递,由处理器在固件上实现参数的自动复制:即用户进程压在3特权级栈中的参数将被自动复制到0特权级栈中。在调用门描述符高32位的低位有一个5bit的字段(参数个数),供处理器使用,最多可传递31个参数。
  2. 调用门选择子的高13位(索引位)乘以8,作为该调用门描述符在GDT中的偏移量,再通过GDTR得到GDT的基址,从而找到门描述符的地址,进而找到门描述符。
  3. 门描述符中记录的是内核例程所在代码段的段选择子和偏移量,由此得到内核例程的起始地址。

调用门示例

假设CPU目前在执行用户进程1,CPU的当前特权级CPL = 3,用户进程试图从磁盘中读数据到自己的数据段中,磁盘操作需要交由内核处理,其向调用门提供参数,其中一项是数据段的选择子
情况1:用户提供的是自己的数据段选择子,RPL为3,通过调用门后执行内核代码段,其CPL变为0,访问此DPL = 3的数据段,则操作系统检查:CPL <= DPL成立,RPL <= DPL成立,成功。
情况2:用户提供的是内核的数据段选择子,RPL为0,但通过调用门时操作系统对选择子的RPL进行修改,改为其CPL值,即为3,通过调用门后CPL = 0,此时若访试图访问DPL = 0 的内核数据段,则不满足RPL <= DPL的条件,失败。

用户进程的切换

用户进程需要使用iretd返回指令才能上CPU运行,CPU在执行iretd指令时作特权检查,检查DS、ES、FS、GS用于存储选择子的段寄存器,若有任一个段寄存器所指的段描述符的DPL权限高于从iretd命令返回后的CPL,CPU会将该段寄存器赋值为0,以免低特权级程序有访问高特权级资源的机会。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值