处理器通过什么规则判断资源请求或者代码跳转是否合法?
数据段的访问规则:(数据段无可执行属性)
访问者权限(CPL)高于或者等于数据段权限(DPL)
请求特权级(RPL)高于或者等于数据段权限(DPL)
即(CPL <= DPL)&& (RPL <= DPL)
上面的公式没有阐述CPL和RPL的关系,这是因为对数据段进行访问的时候CPL和RPL是没有关系的。
怎么判断一个段是不是数据段呢?
这就要根据有无可执行属性来判断了,无可执行属性就是数据段了。
访问示例:
CPL=2, RPL=1, DPL=3,是否合法?合法
CPL=0, RPL=3, DPL=2,是否合法?不合法
CPL=0, RPL=1, DPL=2,是否合法?合法
合法性的检查发生在对段寄存器赋值的时候,例如mov ds, ax。
每个特权级都有不同的栈,每个特权级只能使用自己特权级的栈,例如,0特权级只能使用0特权级的栈,3特权级只能使用3特权级的栈。
如果0特权级使用2特权级的栈,则在mov ss, ax的时候会报错。
对于栈来说段描述符的DPL也要和栈段选择子的RPL相等。
对于栈段来说:
当为ss寄存器赋值时,使用规则(CPL==RPL)&& (CPL==DPL)保证特权级的匹配。
定义栈的时候要让RPL和DPL的值相同。
结论:
选择子被段寄存器加载时,会进行保护模式的检查
检查选择子的下标是否合法(段描述符的合法性,前面博客写过)
检查特权级是否合法,(CPL & RPL <= DPL)
检查特权级时CPL和RPL之间不会进行比较(仅对普通数据段的访问成立,不包括栈段的使用)
代码段的分类:
非系统段(S=1)
一致性代码段
非一致性代码段
系统段(S=0)
LDT, TSS, 各种门结构
S是段描述符中的一个位域。
这里的系统不是指的操作系统,而是处理器本身。
LDT和TSS是用于多任务实现的结构,一般叫做系统段。
非系统段就是我们定义的数据段、代码段等。
代码段又分为两类,一致性代码段和非一致性代码段,这个概念就和段描述符中的TYPE位域有关了。
TYPE域有5位,A、R、C、X、S。
一致性代码段:X=1 C=1
非一致性代码段:X=1 C=0
一致性和非一致性有什么区别呢?
代码段之间的跳转规则(我们这里讲解的跳转是不借助门描述符的)
非一致性代码段
代码段之间只能平级转移(CPL==DPL, RPL<=DPL)CPL和RPL不用比较
一致性代码段
支持低特权级代码向高特权级代码的转移(CPL>=DPL),高跳到低不允许
虽然可以成功转移到高特权级代码段,但是当前特权级不变,特权级不变,栈就不变
非一致性代码段能跳转到一致性代码段,可以从低特权级的代码段跳转到高特权级代码段,高跳到低不允许
一致性代码段能跳到非一致性代码段(这时在一致性代码段中的特权级是由原来跳转到这个代码段时非一致性代码段的特权级决定的,因为上面我们说了特权级不变)
数据段只有一种,没有一致性和非一致性的区分,并且数据段不允许被低特权级的代码段访问。
降特权级跳转(retf)时,目标代码段特权级与目标栈段特权级必须完全相同,即(ss.rpl==cs.rpl)&& (ss.dpl==cs.rpl)
结论:
特权级降低转移时,retf指令会触发栈段的特权级检查(通过选择子中的rpl进行检查)
一致性代码段可以直接跳转到其他同级非一致性代码段执行
一致性代码段和非一致性代码段中的代码没有本质的区别,这两种代码段仅仅是跳转时使用的合法性判断规则不同,因此,一致性代码段到非一致性代码段的直接同级跳转是合法的。
小技巧:
大多数情况下,选择子中的RPL和对应段描述符中的DPL可设置为相同值。
小结:
CPL、RPL和DPL是处理器进行特权级保护的依据。
对于数据段,CPL<=DPL,RPL<=DPL
对于非一致性代码段,CPL==DPL,RPL<=DPL
对于一致性代码段,CPL>=DPL,转以后CPL不变。
本博客参考狄泰软件学院唐佐林操作系统视频教程