now*_*wat 1 c system-calls linux-kernel userspace
我正试图建立一个关于Linux内核和用户空间如何工作的"大图",我很困惑.我知道用户空间利用系统调用与内核"交谈",但我不知道如何.我试图阅读C库和内核源代码,但它们很复杂且不易理解.我还阅读了几本关于操作系统概念事实的书籍,比如管理进程,内存,设备,但它们没有明确"转换"(用户空间 - >内核).那么,用户空间和内核空间之间的转换到底发生了什么?C库如何运行在机器中运行的Linux内核中的代码?
打个比方:假设有一所房子.房子被锁了.打开房子的关键在于房子内部.屋内只有一个人,内核.用户空间是有人试图进入房子.我的问题是:内核如何知道房子外面有人想要密钥,哪个机制允许用该密钥打开房子?
Krz*_*ski 10
这很安静 - 这个人可以用门铃让内核知道它在外面等着.在我们的例子中,这个门铃通常是一个特殊的CPU异常,软件中断或允许用户空间使用并且内核可以处理的专用指令.
所以程序是这样的:
context switch),读取系统调用号和参数并调用正确的系统调用例程.它还将确保将返回值放在适当的位置以供用户空间读取,并在syscall例程完成时调度进程(恢复其上下文).例如,要让内核知道你想在x86_64上调用syscall,你可以sysenter在%rax寄存器中使用带有系统调用号的指令.参数可通过寄存器(如果我没记错)通过%rdi,%rsi,%rdx,%rcx,%r8和%r9.
您还可以使用32位x86 CPU上使用的旧方法 - 软件中断号0x80(int 0x80指令).再次,系统调用号在指定%rax的寄存器和参数去(同样,如果我没有记错)%ebx,%ecx,%edx,%esi,%edi,%ebp.
ARM非常相似 - 您将使用"supervisor call"指令(SVC #0).您的系统调用号将进入r7注册,所有参数将转到寄存器r0-r6,系统调用的返回值将存储在r0.
其他架构和操作系统使用类似的技术.细节可能会有所不同 - 软件中断号可能不同,参数可能使用不同的寄存器传递,甚至使用堆栈,但核心思想是相同的.