Linux中的系统调用机制存在疑问

时间:2010-05-11 01:34:40

标签: linux x86 system-calls

我们使用'int'或新的'syscall / sysenter'指令从ring3转换到ring0。这是否意味着需要为内核修改的页表和其他内容是由'int'指令自动完成的,或者'int 0x80'的中断处理程序将执行所需的操作并跳转到相应的系统调用。

同样,当从系统调用返回时,我们再次需要转到用户空间。为此,我们需要知道用户空间中的指令地址以继续用户应用程序。存储的地址在哪里。 'ret'指令是否会自动将ring从ring3更改为ring0或者这种环更换机制发生在何处/如何进行?

然后,我读到从ring3变为ring0并不像从ring0变为ring3那样昂贵。为什么会这样?

谢谢, 巴拉

1 个答案:

答案 0 :(得分:6)

切换到内核模式时页面表不会更改 - 虚拟地址空间的内核部分只是标记为只能在ring0中访问,因此它只是可以访问。内核在更改当前进程时会更改页表。

int 0x80指令由陷阱门提供,它为处理器提供跳转到CS:EIP对的地址。新的CS(代码段选择器)包括一个0的CPL(当前权限级别),它将转换为ring0。

由于从ring3到ring0的转换,处理器还从TSS(任务分段选择器)中获取SS:ESP的新值,并将旧值保存在TSS中。这从用户模式堆栈切换到内核堆栈。

然后将先前的CS:EIP推送到内核堆栈(这是用户空间中的返回地址)。由于int 0x80指令本身,所有这一切都由处理器完成。

IRET指令可用于返回用户空间 - 它从内核堆栈弹出CS:EIP。由于CS包含3的CPL,处理器将切换回ring3,这也会导致它切换回ring3堆栈。