big*_*iao 2 linux operating-system system-calls linux-kernel
这是一个关于系统调用期间发生的细节的问题。
然而,让我惊讶的一件事是 TSS 为不同的权限维护不同的堆栈。也就是说,在用户模式和系统模式下运行的代码使用不同的堆栈上下文。
既然系统调用实际上是一个函数调用,为什么我们不能重用用户堆栈并为其创建一个新的堆栈框架呢?
系统调用和函数调用是完全不同的两件事。内核空间和用户空间是两个独立的世界,为了简单性和安全性,您希望尽可能将它们分开。内核操作必须对用户程序透明,并且内核数据必须仅对内核可见。系统调用不仅仅是函数调用,内核完成的工作需要对用户程序保持不可见。
使用单独堆栈的最简单原因是它们实际上属于两个不同的程序:一个是用户空间程序,另一个是操作系统。这些堆栈具有不同的大小和偏移量,因此单独管理要简单得多。想象一下,如果用户程序在已耗尽所有可用堆栈的叶函数中进行系统调用,会发生什么:内核要么无法执行它并崩溃,要么必须检测到这一点并通过分配更多空间来避免崩溃在当前堆栈的顶部。这比保持两个堆栈分开要复杂得多,并且很难保持它对用户程序透明(也就是说,除非您随后恢复这些更改,这会使情况更加复杂)。
除了上述之外,将系统调用视为简单的函数调用,从而使内核使用与调用程序相同的堆栈,会在程序的堆栈上留下大量内核数据(基本上是内核使用的每个局部变量)处理系统调用时的函数)。这是不应该发生的副作用,因为它会将大量内核数据和地址暴露给用户空间,这也是一个安全问题。如果内核要使用与发出系统调用的用户程序相同的堆栈,则每个内核函数都需要在返回之前“清除”使用的所有局部变量(甚至清除堆栈上保存的返回地址),这会使整个操作系统变慢很多,而且对用户程序来说仍然不透明。
| 归档时间: |
|
| 查看次数: |
1294 次 |
| 最近记录: |