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

bal*_*486 3 linux x86 system-calls

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

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

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

谢谢,巴拉

caf*_*caf 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堆栈.