swi SYS_ERROR0 在 arm linux 内核中做了什么?

What does swi SYS_ERROR0 do in arm linux kernel?

下面是定义 arm linux (arch/arm/kernel/entry-armv.S)

的复位向量代码
vector_rst:
 ARM(   swi     SYS_ERROR0      )
 THUMB( svc     #0              )
 THUMB( nop                     )
        b       vector_und

指令swi SYS_ERROR0有什么作用?我查的时候发现SYS_ERROR0在arch/arm/kernel/asm-offsets.c

DEFINE(SYS_ERROR0,            0x9f0000);

我无法在互联网上找到与它相关的任何内容。有人可以解释这条指令的作用吗? SYS_ERROR0 是什么?

I was unable to find anything related to it on internet. Can someone explain what does this instruction do ? What is SYS_ERROR0 ?

DEFINE(SYS_ERROR0,            0x9f0000);

swi instruction 通常是从用户模式到系统模式的调用。即,用户 space 到 Linux 内核。较低的数字是标准 Linux 系统调用,例如 open()sbrk()

如果您查看 arch/arm 中的 uapi/asm/unistd.h,您会看到一些定义,例如 __ARM_NR_BASE,即 __NR_SYSCALL_BASE+0x0f0000。对于 OABI 系统,这可以是 0x9f0000。基本上,这些是 secret 系统调用,它们是 ARM 特定的内核调用。例如,__ARM_NR_get_tls 仅用于 ARM 上的 libc 线程管理。其他 CPUs 可能有不同的非系统调用机制来做同样的事情 and/or 系统调用接口可能不同于 ARM CPU.

所以SYS_ERROR0是一个特殊的ARM系统调用。顺便说一下,asm-offset.c从来没有被直接使用过。它被编译并通过脚本扫描对象以获得汇编器对结构的偏移等。因此,如果编译器以不同方式打包结构,那么理论上,汇编器将与编译器版本同步。我们从这里开始,

.L__vectors_start:
    W(b)    vector_rst
    W(b)    vector_und
    W(ldr)  pc, .L__vectors_start + 0x1000
    W(b)    vector_pabt
    W(b)    vector_dabt
    W(b)    vector_addrexcptn
    W(b)    vector_irq
    W(b)    vector_fiq

swi是由W(ldr) pc, .L__vectors_start + 0x1000处理的向量,所以代码在向量table之后4k。这是 vector_swi,您可以在 entry-common.S. There are two methods of making a syscall. The older one (OABI) encodes the call in the SWI instruction. This is bad as the ICACHE must be examined as data (DCACHE). The newer systems pass the syscall in r7. There are two jump tables; sys_call_table and sys_oabi_call_table to handle OABI and the newer mechanism. In both case, higher __NR_SYSCALL_BASE are special cased and use arm_syscall in traps.c 中看到代码。所以SYS_ERROR0就是traps.c中的case 0: /* branch through 0 */代码。消息 branch through zero 被打印出来(因为用户 space 跳转到地址 0 处的重置向量)并且用户 space 得到一个信号。