Linux中系统调用机制的疑问
收藏

我们使用“int”或新的“syscall/sysenter”指令从ring3转换到ring0。这是否意味着需要为内核修改的页表和其他内容是由“int”指令自动完成的,或者“int 0x80”的中断处理程序将执行所需的内容并跳到相应的系统调用。
另外,当从系统调用返回时,我们再次需要转到用户空间。为此,我们需要知道用户空间中的指令地址才能继续用户应用程序。那个地址存储在哪里?“ret”指令是否自动将环从ring3更改为ring0,或在何处/如何执行此环更改机制?
然后,我读到从Ring3改为Ring0的代价不如从Ring0改为Ring3的代价高。为什么会这样?是吗?
谢谢,
巴拉


最佳答案:

切换到内核模式时不会更改页表-虚拟地址空间的内核部分只是简单地标记为仅在ring0中可访问,因此它只是变得可访问。内核在更改当前进程时更改页表。
int 0x80指令由trap gate提供服务,trap gate为处理器提供地址以作为cs:eip对跳转到。新的cs(代码段选择器)包含一个cpl(当前特权级别)0,它影响到到ring0的转换。
由于从ring3转换到ring0,处理器还从tss(任务段选择器)中为ss:esp获取新值,并将旧值保存在tss中。这将从用户模式堆栈切换到内核堆栈。
然后将前面的cs:eip推送到内核堆栈上(这是用户空间中的返回地址)。由于int 0x80指令本身,所有这些都是由处理器完成的。
IRET指令可用于返回用户空间-它从内核堆栈弹出cs:eip。由于cs包括一个3的cpl,处理器正在切换回ring3,这导致它也切换回ring3堆栈。

    公众号
    关注公众号订阅更多技术干货!