我们使用“int”或新的“syscall/sysenter”指令从ring3过渡到ring0。这是否意味着需要为内核修改的页表和其他内容由“int”指令自动完成,或者“int 0x80”的中断处理程序将执行所需的内容并跳转至相应的系统调用。
同样,从系统调用返回时,我们再次需要进入用户空间。为此,我们需要知道用户空间中的指令地址以继续用户应用程序。该地址存储在哪里。 “ret”指令是否自动将环从ring3更改为ring0,或者该环更改机制在何处/如何发生?
然后,我读到从ring3更改为ring0不如从ring0更改为ring3那样昂贵。为什么会这样呢?
谢谢,
巴拉
最佳答案
切换到内核模式时,页面表不会更改-虚拟地址空间的内核部分仅被标记为仅在ring0中可访问,因此它变为可访问。内核在更改当前进程时会更改页表。int 0x80
指令由陷阱门提供服务,陷阱门为处理器提供了作为CS:EIP对跳转到的地址。新的CS(代码段选择器)的CPL(当前特权级别)为0,这会导致过渡到ring0。
由于从ring3到ring0的过渡,处理器还从TSS(任务段选择器)中获取SS:ESP的新值,并将旧值保存在TSS中。这将从用户模式堆栈切换到内核堆栈。
然后将先前的CS:EIP推送到内核堆栈(这是用户空间中的返回地址)。由于int 0x80
指令本身,所有这些操作都由处理器完成。IRET
指令可用于返回用户空间-它从内核堆栈中 pop CS:EIP。由于CS的CPL为3,因此处理器将切换回ring3,这也会导致处理器也切换回ring3堆栈。
关于linux - Linux中系统调用机制的疑问,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2807526/