作者:罗宇哲,中国科学院软件研究所智能软件研究中心
上一期中我们介绍了ARM Linux内核中的系统调用和定义系统调用的流程,这一期我们将介绍系统调用的执行过程。
一、ARM Linux内核中系统调用的执行过程
在第二十九期和第三十期中,我们介绍过ARM Linux内核中的异常向量表和异常处理的一般流程。系统调用属于同步异常的范畴,因此遵循异常处理的一般流程。ARM Linux 内核的异常向量表在/kernel-4.19/arch/arm64/kernel/entry.S文件中:
该表从上到下共有四组,系统调用则属于第三组和第四组:
- 第三组为64位应用程序在异常级别EL0生成的异常。例如64位用户态程序发生系统调用,处理器从异常级别EL0切换到异常级别EL1,并且使用aarch64执行状态处理异常;
- 第四组为32位应用程序在异常级别EL0生成的异常。例如32位用户态程序发生系统调用,处理器从异常级别EL0切换到异常级别EL1,并且使用aarch32执行状态处理异常;
两组中的sync项即为同步异常(包括系统调用)的入口。以64位应用程序的系统调用为例,通过sync入口程序跳转到el0_sync处(这是因为kernel_ventry宏会在跳转的目标label前加入el字符串和输入的异常级别),el0_sync入口代码在entry.S文件中:
/*
* EL0 mode handlers.
*/
.align 6
el0_sync:
kernel_entry 0
mrs x25, esr_el1 // read the syndrome register
lsr x24, x25, #ESR_ELx_EC_SHIFT // exception class
cmp x24, #ESR_ELx_EC_SVC64 // SVC in 64-bit state
b.eq el0_svc
cmp x24, #ESR_ELx_EC_DABT_LOW // data abort in EL0
b.eq el0_da
cmp x24, #ESR_ELx_EC_IABT_LOW // instruction abort in EL0
b.eq el0_ia
cmp x24, #ESR_ELx_EC_FP_ASIMD // FP/ASIMD access
b.eq el0_fpsimd_acc
cmp x24, #ESR_ELx_EC_SVE // SVE access
b.eq el0_sve_acc
cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception
b.eq el0_fpsimd_exc
cmp x24, #ESR_ELx_EC_SYS64 // configurable trap
b.eq el0_sys
cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception
b.eq el0_sp
cmp x24