DPL,RPL,CPL关系详解(2) 牛B的解释

来源:百度文库 编辑:神马文学网 时间:2024/04/27 22:41:22
RPL是段选择子里面的bit 0和bit 1位组合所得的值
但这里要首先搞清楚什么是段选择子,根据Intel 的文件(IA-32 IntelR Architecture Software Developer‘s Manual, Volume 3System Programming Guide)它是一个16Bit identifier (原文:A segment selector is a 16-bit identifier for a segment). 但 identifier 又是什么. identifier 可以是一个变数的名字( An identifier is a name for variables), 简单的说它可以就是一般意义的变数. 这里 16-bit identifier for a segment 可以就是一个一般意义的16bit变数但同时要求对它的值解释的时候必须跟据Intel定下的规则---也就是bit 0和bit 1位的组合值就是RPL等等…
因此在程序里如果有需要的话你可以声明一个或者多个变数来代表这些段选择子,这样的话你的程序在某一时刻就可以有很多段选择子,当然有那么多段选择子就有那么多RPL.可以这样说程序有多少个是RPL是你怎样看待你自己声明的变数.
程序的CPL(CS.RPL)是CS register 里bit 0和bit 1 位组合所得的值.在某一时刻就只有这个值唯一的代表程序的CPL.
而DPL是段描述符中的特权级, 它的本意是用来代表它所描述的段的特权级. 一个程序可以使用很多段(Data,Code,Stack)也可以只用一个code段等.在正常的情况下当程序的环境建立好后,段描述符都不需要改变-----当然DPL也不需要改变.
所有的程序转跳,CPU都不会把段选择子的RPL赋给转跳后程序的CS.RPL.
转跳后程序的CPL(CS.RPL)只会有下面的俩种可能
转跳后程序的CPL(CS.RPL) = 转跳前程序的CPL(CS.RPL)

转跳后程序的CPL(CS.RPL) = 转跳后程序的CodeDescriptor.DPL
以 Call 为例(只能跳到等于当前特权级或比当前特权级更高的段):
怎样决定这两种选择,这就要首先知道转跳后程序的段是一致代码段还是非一致代码段.其实也很简单,规则如下:
如果能成功转跳到一致代码段, 转跳后程序的CPL(CS.RPL) = 转跳前程序的CPL(CS.RPL),(转跳后程序的CPL继承了转跳前程序的CPL)
如果能成功转跳到非一致代码段, 转跳后程序的CPL(CS.RPL) =转跳后程序的Descriptor.DPL。(转跳后程序的CPL变成了该代码段的特权级.我在前面提到DPL是段描述符中的特权级, 它的本意是用来代表它所描述的段的特权级)
怎样才能成功转跳啦?
这里有四个重要的概念:
1).段的保护观念是高特权级不找低特权级办事,低特权级找高特权级帮忙,相同的一定没问题.(这样想逻辑是没错,事实对不对就不知道.)也就是县长不找乡长,乡长不求农民,反过来农民求乡长,乡长找县长.这个概念是最重要的。
2) 一致代码段的意义: 让客人很方便的利用主人(一致代码段)的东西为自己办事.但客人这身份没有改变NewCS.RPL=OldCS.RPL所以只能帮自己办事。比方说乡长有一头牛,农民可以借来帮自己种田,但不能种别人的田.但是如果你是乡长当然可以种乡里所有的田。
3) 非一致代码段的意义:主人(非一致代码段)可以帮客人但一定是用自己的身份NewCS.RPL= DestinationDescriptorCode.DPL这里可能有安全的问题, 搞不好很容易农民变县长。主人太顽固了一定要坚持自己的身份,有什么方法变通一下,来个妥协好不好。好的,它就是RPL的用处
4) RPL: 它让程序有需要的时候可以表示一个特权级更低的身份Max(RPL,CPL)而不会失去本身的特权级CPL(CS.RPL)。有需要的时候是指要检查身份的时候。 很难理解,看这个故事而故事的人物是来自另外的帖子的。
一个农民(低特权级)请县长(高特权级)打听一种超级种子,如果找到的话帮忙拿一点回来,听闻这种超级种子可让收成倍增。县长说:好!我认识很多当官的,我可以帮你打听一下哪里有,但是有些地方如果需要表示身分的话我只能说我是农民的代理人。县长利用自己的身份很容易找到了种子在哪里---找的时候没有人问起他代表谁。县长问种子管理员可不可以给他一点,管理员说种子不能给农民因为种子还在试验阶段,我们可以给县长让他们带回当地的专家来帮忙一起做试验,但是一定要县长来申请。那你是谁?县长说我是农民的代理人,因为县长保证他会这样回答的(他也不知道那农民是不是专家),管理员当然不给。县长没办法只能告诉农民拿不到种子。这件事里面县长是以县长的身份帮农民找到种子,但需要表示身分的时候他说只是农民的代理人。这样做县长可以帮人但也不会给别人利用。(农民可能把种子拿回来卖钱也说不定,没人知道)
在这里RPL就是县长的另一个身份---农民的代理人也就是农民---他会带在身上,人家没有问他的时候他不会告诉别人,所以别人也就以县长的身分来看待他。当查身份的时候他才告诉你---我是农民的代理人。
RPL保存在段选择子里,而段选择子可以是变数(要不然县长怎样带在身上,这样县长也有机会多代表多一些人),当你用Call的时候用上这些变数,这些变数就成了段选择子
事实上RPL跟段本身的特权级DPL和当前特权级CPL没有什么关系,因为RPL的值在成功转跳后并不赋给转跳后的CS.RPL.
还是要问怎样才能成功转跳啦?
普通转跳(没有经过Gate 这东西)
目标是一致代码段:
CPL(CS.RPL)>=DestinationDescriptorCode.DPL  就可以啦,其他RPL是不检查的
转跳后程序的CPL(NewCS.RPL) = 转跳前程序的CPL( OldCS.RPL)
上面的安排就是概念1,2的意思。
目标是非一致代码段:
CPL(CS.RPL)=DestinationDescriptorCode.DPL AND RPL<= CPL(CS.RPL)
转跳后程序的CPL(NewCS.RPL) = DestinationDescriptorCode.DPL
上面的安排就是概念3的意思和部分1的意思----主人(一致代码段)只帮相同特权级的帮客人做事。
To be continuous
Continuous
2006/04/13
现在说明一下gate 的用法:
gate简单来说可以想象成政府为人民提供的一个政府诉求中心,它可以集中收集人民对政府的要求和投诉。。。。。。然后把这些诉求发给相关的政府部门来处理。
这里继续用农民想要一种超级种子的故事来说明一下。我觉得上面的故事还是不太贴切RPL的用法,在这里一起加上gate的用法再说明一下。
Intel政府为了收集广大市民的意见在政府的土地上建立了一所诉求中心,在它的入口放了一块告示写着:我们这里只欢迎普通的市民,如果你是当官的就不要来啦。Intel 政府的诉求中心总是有这样的告示,要求你的身份如果是这档次或者在这个档次以下的我们就欢迎,不是的就不要来了。这是Intel政府的特色,谁也改不了。
农民想要超级种子,不知道找Intel政府那个部门帮忙。但是他知道可以向Intel政府的诉求中心反映一下。他来到了诉求中心并通过了身份检查,交了申请文件就回家等消息。身份检查在这里须要说明一下,原来身为Intel的市民徐了有出1)世纸外,在身上还可以带上两种证件2)身份证,3)工作证, 在身上带多少张工作证是没问题的,只是在身份检查的时候你只能拿一张出来,这种工作证上的身份是自己填的,填什么身份都可以,这次发财了,填上一个大官不是很好。你想得美,在身份证里也有就放着你天生的身份(身份证的资料是依照世纸外来填),在身份检查的时候身份证跟工作证一起对比,政府只认档次低的那一个。这样看来工作证对农民来说是没有什么好处,是的,真的是没有什么好处。农民只要把那张工作证填上身份证的资料就是了。通过了诉求中心的身份检查,诉求中心的人员就把你的文件交给相关政府部门,相关的政府部门也会再次对你的身份进行检查,但这一次它不会检查你的那张工作证,它只会检查你的身份证。以办事原则的不同,Intel政府的部门可以分为两种类型1)一致代码段类型,2)非一致代码段类型。 不同类型的部门对于这种已通过诉求中心的人的身份检查的规则是一样的(如果不是通过诉求中心”gate”, 身份检查的规则可以不一样,请看上面的说明)。它们都要求身份证的身份等于或者小于该部门的人员天生身份---写在出世纸上的那一个身份。它们的不同在于身份检查过关后它们会用什么方式来为你办事。它们的办事原则也就是我在提到的概念2及概念3。写得太累了,我就把前面已有的东西拷贝下来吧:
2) 一致代码段的意义: 让客人很方便的利用主人(一致代码段)的东西为自己办事.但客人这身份没有改变NewCS.RPL=OldCS.RPL所以只能帮自己办事。比方说乡长有一头牛,农民可以借来帮自己种田,但不能种别人的田.但是如果你是乡长当然可以种乡里所有的田。
3) 非一致代码段的意义:主人(非一致代码段)可以帮客人但一定是用自己的身份NewCS.RPL= DestinationDescriptorCode.DPL这里可能有安全的问题, 搞不好很容易农民变县长。主人太顽固了一定要坚持自己的身份,有什么方法变通一下,来个妥协好不好。好的,它就是RPL的用处
诉求中心的人员就把你的文件交给了一个一致代码段类型的县长,如果他答应帮你忙的话,他就一定会把自己的身份变成农民的身份(身份证上原本是县长现在变成是农民)。那么县长变成了农民怎样帮忙,他不能问其他的县长,但我们不能排徐县长认识的农民比你多,他可以问更多的农民有关的消息,他是有可能把种子的消息带给你的。这样的做事原则是很小心,但帮忙不多。
如果诉求中心的人员就把你的文件交给了一个非一致代码段类型的县长。这个县长的个性是怎样我们还没有确定。他可能是一个1)热心又谨慎的人,2)热心但不谨慎的人,3)不热心但谨慎人,4)不热心又不谨慎的人。3 跟 4 是一样的,就是不热心,他不会帮你的,所以我们不谈这种人。我们现在就假设县长是热心又谨慎的人。他的合理做法就会像第一个故事里的县长一样,用自己的身份找资料,用代理人的身份要东西(在有需要的时候他拿出那张农民的工作卡让检查人员认为他是农民)。如果县长是热心但不谨慎的人,麻烦可能会发生,因为他可能只会用县长的身份来做事,这样的话,他的身份证和工作证都是县长,他可能为农民拿了他不该拿的东西。在这里要明白一个事情,就是县长是有权自己决定以哪一种方式为农民服务,他可以选择小心,他也可以选择不小心,还可以选择不帮忙。这里要注意的是非一致代码段类型的县长是永远不会改变身份证上的身份的,同时他有权在任何时间改变工作证上的身份。
总结一下:
DPL = 出生证的身份
CPL = 身份证上的身份
RPL = 工作证上的身份
Gate = Intel政府的诉求中心
县长的谨慎不谨慎就是程序员的编程态度的谨慎不谨慎。
事实上没有RPL你也可也做到同样的事情,只要你有方法知道农民是不是农民,只要检查一下它的CPL就可以啦,然后检查一下农民提交的请求是不是合理,然后决定帮不帮忙或者怎样帮忙就行了。
RPL 只是提供了一个硬件的支持让你做起来方便一点。只要大家按着这个方法来做,这些保护的工作就变得容易,但这样就变成机器依赖了。
对于特权级高的进程RPL是作用是防止自己不小心访问到一些资料段。 比方说,如果进程A的CSL=0,它知道它的委托进程B的CPL=3,也知道资料段C的DPL=2,而这资料段是不能让CSL>2的进程访问的。那么如果你是进程A的程序员根本不需要RPL的帮助,也不会试图让进程A访问资料段C的资料, 因为这样做只会浪费时间。当然如果你一定要访问资料段C的资料然后把资料传给委托进程B,这就是你的选择,你真的可以这样做,但后果自负。只是有时候要访问的资料段我们不知道它的DPL是怎么,也不知道能不能让进程B访问,其中的一个解决方法就是把委托进程B的CPL以RPL的方法告诉资料段C让它决定接受或不接受。
由上面的故事可能发现如果没有一致代码段这东西,能成功转跳后的NewCS.RPL= NewDestinationDescriptorCode.DPL,如不能转跳NewCS.RPL=OldCS.RPL= OldDestinationDescriptorCode.DPL。事实上你的程序不用一致代码段也是可以的。
你还可以发现RPL对特权级=3的进程是没有意义的。因为特权级=3的进程只会找人帮忙。
还是要问怎样才能成功经过Gate 这东西转跳转吗?
目标是一致代码段:
1) CPL(CS.RPL) <= GateDescriptor.DPL AND RPL <= GateDescriptor.DPL
2) CPL(CS.RPL) >= DestinationDescriptorCode.DPL, RPL不再检查
转跳后程序的CPL(NewCS.RPL) = 转跳前程序的CPL( OldCS.RPL)
上面的安排就是概念1,2的意思。
目标是非一致代码段:
1) CPL(CS.RPL) <= GateDescriptor.DPL AND RPL <= GateDescriptor.DPL
2) CPL(CS.RPL) >= DestinationDescriptorCode.DPL RPL不再检查
转跳后程序的CPL(NewCS.RPL) = DestinationDescriptorCode.DPL
上面的安排就是概念3的意思和1的意思。