momo zone

调核人的blog

关于kernel注释中iret手动切运行级

为什么要用iret??前面书上说了是为了从特权0的代码切换到特权3的代码中去,但是为什么不用ret呢?
书上说ret也可以返回到特权级低的程序中去呀!

比如把48~62这样改写:



movl  $TSS0_SEL , %eax


itr  %ax


movl  $LDT0_SEL , %eax


lldt  %ax


movl  $0,  current


sti


pushl  $0x17


pushl  $init_stack


pushl  $0x0f


push  $task0


ret

当然这里需要留意iret还将弹出标志寄存器(popf),不过即使这样也没有影响。

其实这样是可以的,因为:
ret指令的段间跳转会改变特权级,但是只针对(数值上)特权级值低的处理程序,也就是内核态才能用(因为linux只有0和3)。
当ret指令面对的是目标cs的RPL在数值上大于CPL,一个特权级返回才发生。就是由0特权级返回到3。

检查的过程是,CPL的特权级要高于目标CS的RPL,而目标CS的RPL要等于目标段描述符的DPL(针对非一致性代码)!

所以,在内核态,这样也可以实现向用户态的转移。

ret前,特权级是0,CS是0x0f,特权级是3,而0x0f对应的段描述符是非一致代码,而且DPL
=3,满足上面的条件,所以,可以起到特权级的变化,而且堆栈也随之变化。

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: