系统调用如何从用户空间到内核空间并返回用户空间?

a.s*_*abh 2 linux linux-device-driver linux-kernel embedded-linux

我研究了一些文章,其中我得到的信息是像 open() 这样的系统调用调用 glibc 中的包装函数,然后引发一个陷阱,将上下文从用户空间切换到内核空间,然后使用 cpu 寄存器来调用系统调用内核空间中的参数/参数。

但我仍然想我缺少系统调用调用的分步过程或详细序列。如果人们能够提供考虑 ARM arch 作为参考的步骤,那就太好了。提前致谢。

小智 5

在 ARM 情况下,软件中断异常用于调用系统调用。它将执行地址存储在物理地址处的函数0x08

Syscall 包装库函数落地到 SYSCALL 的体系结构特定实现(检查sysdeps/unixlibc 源代码目录)。在我们的例子中,sysdeps/unix/sysv/linux/arm/syscall.S将执行来自文件的系统调用。在此函数中,它将存储系统调用号R7R0-R6用于向系统调用发送参数。

示例汇编代码:

     mov  r7, #SYSCALL NO
     mov  r0, #ARG1
     mov  r1, #ARG2
     swi 0x0
Run Code Online (Sandbox Code Playgroud)

当软件异常产生时,vector_swi() <arch/arm/kernel/entry-common.S>被调用。该函数从 R7 获取系统调用号,从 中查找并执行注册的函数地址sys_call_table

检查以下内核文件以获取实现细节:

  1. 包含/linux/syscalls.h
  2. arch/arm/include/asm/unistd.h
  3. arch/arm/kernel/calls.S
  4. 拱门/手臂/内核/entry_common.S
  5. 拱门/arm/kernel/sys_arm.c