Linux中系统调用机制的疑惑

4
我们使用'int'或新的'syscall/sysenter'指令从ring3转换到ring0。这是否意味着需要修改内核的页表和其他内容会自动由'int'指令或'int 0x80'的中断处理程序完成所需的操作并跳转到相应的系统调用?
另外,当从系统调用返回时,我们再次需要进入用户空间。为此,我们需要知道用户空间中指令的地址以继续用户应用程序。该地址存储在哪里?'ret'指令是否会自动将环从ring3更改为ring0,或者这种环更改机制发生在何处/如何发生?
然后,我读到从ring3到ring0的转换不像从ring0到ring3的转换那样昂贵。为什么会这样?
谢谢, Bala

这篇文章:Linux 2.6中基于Sysenter的系统调用机制应该能回答你大部分的问题。 - WhirlWind
1个回答

7
当切换到内核模式时,页表不会改变-虚拟地址空间的内核部分仅被标记为只能在ring0中访问,因此它变得可访问。内核在更改当前进程时更改页表。 int 0x80指令由陷阱门提供服务,该门提供处理器跳转到的地址作为CS:EIP对。新的CS(代码段选择器)包括CPL(当前特权级)为0,这会影响到ring0的过渡。
由于从ring3到ring0的转换,处理器还从TSS(任务段选择器)中获取了SS:ESP的新值,并将旧值保存在TSS中。这将从用户模式堆栈切换到内核堆栈。
然后,先前的CS:EIP被推送到内核堆栈上(这是用户空间中的返回地址)。所有这些都是由于int 0x80指令本身而由处理器完成的。 IRET指令可用于返回到用户空间-它从内核堆栈中弹出CS:EIP。由于CS包括CPL为3,处理器正在切换回ring3,这也导致它切换回ring3堆栈。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接