我研究了一些文章,其中我得到的信息是像 open() 这样的系统调用在 glibc 中调用包装函数,然后引发陷阱,将上下文从用户空间切换到内核空间,然后 cpu 寄存器用于在内核空间调用系统调用参数。
但我想我仍然缺少系统调用调用的分步过程或详细顺序。如果人们可以提供考虑 ARM arch 作为引用的步骤,那就太好了。提前致谢。
最佳答案
在 ARM 的情况下,软件中断异常用于调用系统调用。它将执行地址存储在物理地址 0x08
的函数.
Syscall 包装器库函数登陆到 SYSCALL 的体系结构特定实现(检查 sysdeps/unix
libc 源代码目录)。
在我们的例子中,来自 sysdeps/unix/sysv/linux/arm/syscall.S
的系统调用文件将被执行。在此函数中,它将系统调用号存储在 R7
中。
和 R0-R6
用于向系统调用发送参数。
示例汇编代码:
mov r7, #SYSCALL NO
mov r0, #ARG1
mov r1, #ARG2
swi 0x0
当产生软件异常时,vector_swi()
<arch/arm/kernel/entry-common.S>
叫做。此函数从 R7 获取系统调用号,
从 sys_call_table
中查找并执行已注册的函数地址.
检查以下内核文件以了解实现细节:
- include/linux/syscalls.h
- arch/arm/include/asm/unistd.h
- arch/arm/kernel/calls.S
- arch/arm/kernel/entry_common.S
- arch/arm/kernel/sys_arm.c
关于linux - 系统调用如何从用户空间传播到内核空间并返回用户空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24176570/