标签:通过 代码段 共享 程序 决定 一个操作系统的实现 核心 限制 描述符
在IA32的操作系统中,段被分为了4个特权级,分别为0-3级,有时候我们也叫做ring0-ring3,其中,数值越小特权级越高。如下图所示:
图中,核心代码和数据所在的段的特权级都比较高,一般在ring0,而用户程序所在的段的特权级较低,一般在ring3。当低特权级的任务试图在未被允许的情况下访问高特权级的段时,将会产生常规保护错误。
而处理器是如何区分所在段的特权级,进而对其进行保护的呢?这就不得不提到CPL、DPL和RPL三者了。但是在开始之前,我们需要先了解一下一致代码段和非一致代码段。
在操作系统中,我们有些高特权级的代码是希望被低特权级的程序所访问的,比如一些库函数,于是我们将这些高特权级代码放在一个叫做一致代码段的段里。而有些高特权级的代码,我们并不想让低特权级的程序所访问,于是我们把他们放在一个叫做非一致代码段的段里。具体来说,当通过call或者jmp指令转移到其它段时(即访问其他段),当转移的目标是一个优先级更高的一致代码段时,我们是可以进行访问的,但是当前的特权级会被延续下去;当转移的目标是一个优先级更高的非一致代码段时,这时的访问会引起常规保护错误(除非使用调用门或任务门)。
总结来说:
所遵循的规则如下图所示:
CPL全称Current Privilege Level,顾名思义,CPL代表的是当前执行的任务和程序的特权级。它存储在cs和ss的第0位和第1位上。一般情况下,CPL等于代码所在段的特权级,当程序转移到不同的代码段时,处理器将改变CPL的值。
但是当访问一致代码段时,并不会改变CPL,正如一致代码段中所说,一致代码段可以被低特权级的程序所访问,但是并不会改变特权级,所以也就不会改变CPL,这就是与上面加粗的“一般情况”相对的“非一般情况”。
DPL全程为Descriptor Privilege Level,它代表段或者门的特权级。他被存储在段描述符或者门描述符属性中的DPL字段上。
当当前的代码段试图访问一个段或者门时,DPL将会和CPL以及段或者门选择子的RPL相比较,而对于段或者门类型的不同,比较规则也不同,具体如下:
总结一下就是:
RPL全称是Requested Privilege Level。RPL保存在段选择子的第0位和第1位上。我们在上文说了当一个段访问另一个段时,CPL与DPL的比较规则,但是仅仅比较CPL和DPL是不够的,处理器还要通过检查RPL来确定能否访问另一个段。
操作系统往往用RPL来避免低特权级应用程序访问高特权级段内的数据,即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的,当RPL的值比CPL大的时候,RPL将起决定性作用。也就是说,只有当CPL和RPL都小于要访问的数据段的DPL时,才有权限访问该数据段。关于为什么引入RPL的讨论还是比较复杂的,此处不再深入探讨。
完
参考:
标签:通过 代码段 共享 程序 决定 一个操作系统的实现 核心 限制 描述符
原文地址:https://www.cnblogs.com/tcctw/p/11332551.html