接上文:
提供了4种门的原因是,它们都有各自的应用环境,但它们都是用来实现从低特权级的代码段转向高特权级的代码段,咱们这里也只讨论有关特权级的功用:
- 1.调用门
call和jmp指令后接调用门选择子为参数,以调用函数例程的形式实现从低特权向高特权转移,可用来实现系统调用。call指令使用调用门可以实现向高特权代码转移,jmp指令使用调用门只能实现向平级代码转移。
- 2.中断门
以int指令主动发中断的形式实现从低特权向高特权转移,linux系统调用便用此中断门实现,以后咱们在实现中断时会展开细说。
- 3.陷阱门
以int3指令主动发中断的形式实现从低特权向高特权转移,这一般是编译器在调试时用,本书中咱们不用过多关注。
- 4.任务门
任务以任务状态段TSS为单位,用来实现任务切换,它可以借助中断或指令发起。当中断发生时,如果对应的中断向量号是任务门,则会发起任务切换。也可以像调用门那样,用call或jmp指令后接任务门的选择子或任务TSS的选择子。
坦白说,现代操作系统很少用到调用门和任务门,在咱们的系统中也只用到了中断门,而陷阱门是供调试器用的,咱们并未打算支持应用程序的调试,一方面工作量较大,另一方面违背咱们的初衷,就是想通过更少的代码了解操作系统原理。
不知道大伙儿有没有想过,为什么可以使用门结构进入高特权级呢?这肯定是cpu硬件电路中写好的规则,具体我也不清楚也不需要搞清楚,但我是这样理解的,举个例子,用门提升特权级,就像站在高处的台子上往蹦床上跳一样,人会被蹦床弹得比台子还高。关键点:台子的高度位于蹦床和目标高度之间,至少得和蹦床一样高,这样人才能被弹得更高。其效果如图
实际上,门也是按照这个蹦床原理实现的,我们把“门”分成门槛和门框来比喻:
门的“门槛”是访问者特权级的下限,访问者的特权级再低也不能比门描述符的特权级DPL低,否则访问者连门都进不去,更谈不上使用调用门。即门描述符的DPL特权级要低于或等于当前特权级CPL,即数值上CPL <= 门的DPL,此处可见,门描述符相当于数据段描述符一样,只允许比自己特权级高或相同特权级的程序访问。
门的“门框”是访问者特权级的上限,访问者的特权级再高也不能比门描述符中目标程序所在代码段的DPL高,否则本身的特权级就比目标代码特权级还高的话,还使用门干吗,而且真要是这样的话,这意味是特权级由高向低转移了,这绝对是被禁止的。也就是说,门中包含的目标程序所在的段的特权级DPL要高于或等于当前特权级CPL,即数值上CPL >= 目标代码段DPL,进门之后,处理器将以目标代码段DPL为当前特权级CPL,因此进门之后,就能“一步登天”啦。