特权级

Published: by Creative Commons Licence

特权级

阅读了《一个操作系统的实现》中关于特权级的部分,故此做一下笔记,以做备忘

处理器在进行特权级检查时,通常会检查CPL,RPL,DPL,根据段或门类型的不同,DPL会被区别对待,下面先介绍数据段,代码段的检查,最后再介绍通过调用门访问代码段时的检查

CPL 当前执行的程序或任务的特权级,存储在CS和SS的第0位和第1位上 DPL 表示段或门的特权级,存储在段描述符或门描述符的DPL字段中 RPL 段选择子的第0位和第1位

  • 不使用调用门:

    类型 特权级检查
    数据段 CPL<=DPL && RPL<=DPL
    一致代码段 CPL>=DPL && RPL>=DPL
    非一致代码段 CPL=DPL && RPL=DPL
  • 使用调用门:
    call_gate

    类型 call jmp
    一致代码段 CPL<=DPL_G && RPL<=DPL_G && DPL_B<=CPL CPL<=DPL_G && RPL<=DPL_G && DPL_B<=CPL
    非一致代码段 CPL<=DPL_G && RPL<=DPL && DPL_B<=CPL CPL<=DPL_G && RPL<=DPL && DPL_B=CPL

DPL_G 表示调用门的特权级,DPL_B表示目标代码的特权级,其中如果目标代码段是非一致代码段,则会引起特权级变换,一致代码段则不会,门描述符中的选择子RPL不会参与检查

  • 发生特权级变换时的一系列操作:

1.根据目标代码段的DPL从TSS中选择相应的ss和esp
2.从TSS中读取新的ss和esp
3.对ss描述符进行检查
4.暂时保存当前ss和esp
5.加载新的ss和esp
6.压入保存的ss和esp
7.从旧的栈中复制参数到当前栈中
8.将cs和eip压栈
9.加载调用门中指定的新的cs和eip,开始执行

  • 从高特权级返回低特权级:

1.特权级检查,加载栈上的cs和eip
2.如果有参数,则跳过参数
3.弹出栈上的保存的ss和esp,这时候会检查ss选择子和ss段描述符
4.检查ds,es,fs,gs的值,若哪一个寄存器中选择子指向的段描述符的DPL小于CPL则加载一个空描述符到该段寄存器中