我正试图为Linux内核和用户空间中的工作原理建立一个“全局”,我很困惑。我知道用户空间利用系统调用与内核“对话”,但是我不知道如何。我试图阅读C库和内核源代码,但是它们很复杂并且不容易理解。我也读过几本关于操作系统的概念性事实的书,例如管理进程,内存,设备,但是它们并不能使“转换”(用户空间->内核)变得清晰。那么,用户空间和内核空间之间的转换究竟发生在哪里? C库如何运行计算机中运行的Linux内核中的代码?
打个比方:假设有一所房子。房子被锁了。打开房子的钥匙在房子里面。屋子里只有一个人,内核。用户空间是试图进入房屋的人。我的问题是:内核如何知道房子外面有人要这个钥匙,以及哪种机制可以用那个钥匙打开房子?
这很简单-人们可以使用门铃让内核知道它在外面等着。在我们的情况下,这个门铃通常是特殊的CPU异常,软件中断或允许用户空间应用程序使用且内核可以处理的专用指令。
所以过程是这样的:
context switch
),读取syscall编号和参数并调用适当的syscall例程。它还将确保将返回值放在适当的位置,以供用户空间读取,并在完成syscall例程(恢复其上下文)后安排回退进程。 x86_64上调用syscall,可以在sysenter
寄存器中使用带有syscall编号的%rax
指令。使用寄存器(如果我没记错的话)传递参数%rdi
,%rsi
,%rdx
,%rcx
,%r8
和%r9
。
int 0x80
指令)。再次,在%rax
寄存器中指定系统调用号,然后将参数转到(同样,如果我没记错的话)%ebx
,%ecx
,%edx
,%esi
,%edi
,%ebp
。 >ARM非常相似-您将使用“主管调用”指令(SVC #0
)。您的系统调用号将进入r7
寄存器,所有参数将进入寄存器r0-r6
,并且系统调用的返回值将存储在r0
中。