能力值:
(RANK:260 )
|
-
-
2 楼
其实这个很简单的逻辑,首先你心里要明白descriptor与selector代表的都是一个内存段(segment):
Descriptor描述一个segment,既然叫描述符,它自然就有一些字段用来描述这个段的属性(DPL)。
而selector是用来访问内存的,比如DS用来访问数据段,SS访问堆栈段。selector它的一部分字段用来指出要使用哪个descriptor(换言之,就是要访问哪一个内存段),还有一部分字段,用来表明“我有什么特权来访问这段内存(RPL)”。
而CS与SS中的RPL,就是被称为CPL。因为CPU执行指令,必须要读指令,实际上就是访问CS段中EIP偏移量的内存。因此,CS选择子的特权就代表了“我有多大权力去运行这段代码”,也就是当前特权级(CPL),正因为执行的代码(CODE)的特权也就代表了当前任务(TASK)的特权。至于SS,因为堆栈的特殊性,代码的执行与堆栈密切相关,特别是诸如retn之类的指令,是有可能改变程序执行流程的,因此要求堆栈具有足够的特权。
你把指令执行当成“访问CS:[EIP]内存”,于是就很清楚了:
CPU只是执行“你有足够的特权去访问这个segment的内存吗”这个简单的判断而已。
(其实上面说的有些并不准确,但不防这么理解,接触的时间长了,自然就明白了)
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
谢谢楼上的版主,
还有一个问题,是在<<自动动手写操作系统>>那本书的63页讲的, 说处理器通过检查RPL和CPL来确认一个访问请求是否合法, 即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的,
到这里,我不明白的是目标选择子不就是代表目标描述符吗,目标选择子里的的PRL为什么还要和目标描述符里的DPL相比较呢?我感觉目标有一个特权就够了,为什么还要多此一举呢?
|
能力值:
(RANK:260 )
|
-
-
4 楼
选择子不代表描述符!选择子用来选择描述符,但你选择了并不表示就给你了。
实际情况是,当程序往断寄存器中装载选择子时,处理器检查选择子中的RPL与DPL,如果特权不够,将直接触发保护异常!
而当特权检查通过时,才会将描述符中的基址与限装入SHADOW寄存器,不过我在书上没有看到装入的特权级是RPL还是DPL,个人猜测应该是RPL。
实际访问内存时,硬件只使用SHADOW寄存器的内容,如果不重新装载(哪怕是用原来的值)段寄存器,SHADOW寄存器中的内容就不发生变化。也就是说,修改GDT中的描述符,没有重新装载段寄存器之前是不生效的
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
选择子不就是描述符表里的某一个描述符的偏移吗?
感觉上 选择子就是和描述符一一对应的,这是我以前的理解,以前我一直认为,选择了某一个选择子,就是选择了某一个描述符,现在楼上所说的,和我以前的理解不一样。现在脑子有点转不过来。
另外,在CS等装入选择子时,对于在shadow高速缓冲寄存器里,特权级装入的是PRL还是DPL的问题,
先看一下高速缓冲里面保存的是什么
段寄存器 段基地址 段界限 段属性 存在性 特权级 已存取 粒度 扩展方向 可读性 可写性 可执行 堆栈大小 一致特权
这里把段选择子和描述符全部缓存起来了。段选择子里面有CPL,描述符里面有DPL,这里面还有一些模糊的地方。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
可能这样,在装入高速缓冲寄存器后,CS里面以及高速缓冲寄存器的CS里面的存的是CPL,也就是目标描述符里的DPL值(非一致代码段的情况)。这代表了当前运行的特权级。而在高速缓冲寄存器里面的描述符寄存器里面存的还是DPL。不知道这样理解对不对?!
在书上看到这样一段话:
对于使用调用门的段间调用指令CALL,情形就不同了。由于已置RPL=0,所以可认为RPL<=DPL的条件总能满足。对于一致代码段,在满足CPL>=DPL时发生无特权级变换的转移。对于非一致代码段,当CPL=DPL时,仍发生无特权级变换的转移;当CPL>DPL时,就发生向内层特权级变换的转移,将调用门中的选择子和偏移装入CS和指令指针EIP中,并使CPL保持等于DPL,同时切换到内层堆栈。
|
能力值:
( LV9,RANK:170 )
|
-
-
7 楼
好好的看一看我写的那个贴子吧:
http://linux.chinaunix.net/bbs/thread-1052389-1-1.html
|
能力值:
( LV9,RANK:170 )
|
-
-
8 楼
还是在这回复你吧:
如下指令:
call 0x08:0 // 这是一个 call-gate (使用调用门)
那么:
processor 会做:
1、根据选择子 0x08 在 GDT 中寻找 descriptor
2、processor 检查 descriptor 的 Type 是什么?
这里设为是 call-gate descriptor
3、processor 进行权限检查:
(1) RPL = 00, 因为: selector = 0x08
(2) CPL = 03,(这里设为 03)
(3) DPL 这里要分为两种 DPL:
分别是: call gate descriptor 的 DPL,表示为 DPLg
code segment descriptr 的 DPL,表示为 DPLs
-------------------------------------------------------------------------------
processor 检查:
(1)RPL <= DPLg 且 CPL <= DPLg: 表示当前的运行级别和选择子级别比调用门符级别要高。
因此:调用门符级别必须设为低权限级别,即在这里必须为 DPLg = 3
(2)如果使用的是 call 指令无论代码是 conforming 还是 non-conforming,只要
CPL >= DPLs
都会成功。
4、processor 检查通过后,进行加载 selector 到 CS 中
CS.selector = selector
5、更新 CS 寄存器的内部缓存
(1) CS.slector.RPL = DPLs // 目标代码的运行级别
(2) CS 的 descriptor 结构用 code segment descriptor 来更新
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
楼上的有一点没讲清楚。
4、processor 检查通过后,进行加载 selector 到 CS 中
CS.selector = selector
那CS.selector.RPL的值是多少?
|
能力值:
(RANK:260 )
|
-
-
10 楼
mik出手,就是不同凡响,讲得真清楚。
感谢mik,这里原来我也没有搞明白,现在才知道。
回楼上: CS.slector.RPL = DPLs ,也就是目标代码的权限。因为这里的descriptor是个CALL GATE,因此有DPLg与DPLs两个特权级,DPLg是门的特权级,DPLs是“穿过”门后的代码段的特权级。
|
|
|