Linux Kernel中的系统调用分析
快速鏈接:
.
👉👉👉 個(gè)人博客筆記導(dǎo)讀目錄(全部) 👈👈👈
相關(guān)鏈接:
optee中utee syscall的實(shí)現(xiàn)(系統(tǒng)調(diào)用實(shí)現(xiàn))
文章目錄
- 1、系統(tǒng)調(diào)用在Linux Kernel中的map表(系統(tǒng)調(diào)用的數(shù)組)
- 2、系統(tǒng)調(diào)用的函數(shù)在Kernel中的實(shí)現(xiàn)
- 3、系統(tǒng)調(diào)用的流程
- 4、總結(jié)
1、系統(tǒng)調(diào)用在Linux Kernel中的map表(系統(tǒng)調(diào)用的數(shù)組)
在sys.c中定義了__SYSCALL宏
(kernel-4.19/arch/arm64/kernel/sys.c)#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);例如:
- __SYSCALL(__NR_flock, sys_flock),其實(shí)就是定義__arm64_sys_flock函數(shù)
- __SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl),其實(shí)就是定義__arm64_compat_sys_ioctl函數(shù)
在sys.c中定義并初始化了系統(tǒng)調(diào)用的tab表
(kernel-4.19/arch/arm64/kernel/sys.c)#undef __SYSCALL #define __SYSCALL(nr, sym) [nr] = __arm64_##sym,const syscall_fn_t sys_call_table[__NR_syscalls] = {[0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,#include <asm/unistd.h>};剖析這段代碼,將asm/unistd.h引進(jìn)來了,其實(shí)等價(jià)于下面這句
(kernel-4.19/arch/arm64/kernel/sys.c)const syscall_fn_t sys_call_table[__NR_syscalls] = {[0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,__arm64_compat_sys_io_setup,__arm64_sys_io_destroy,__arm64_compat_sys_io_submit......};2、系統(tǒng)調(diào)用的函數(shù)在Kernel中的實(shí)現(xiàn)
SYSCALL_DEFINE1(arm64_personality, unsigned int, personality) {if (personality(personality) == PER_LINUX32 &&!system_supports_32bit_el0())return -EINVAL;return ksys_personality(personality); }#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)#define SYSCALL_DEFINEx(x, sname, ...) \SYSCALL_METADATA(sname, x, __VA_ARGS__) \__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)在kernel中使用SYSCALL_DEFINEx定義的地方,都是在定義系統(tǒng)調(diào)用函數(shù),例如:
這里定義的SYSCALL_DEFINE1(setgid, gid_t, gid),其實(shí)就是定義__arm64_sys_setgid
3、系統(tǒng)調(diào)用的流程
由于Userspace中C語(yǔ)言使用的libc庫(kù)代碼,我們?cè)趉ernel中是看不到,所以就不做具體分析了。但可以知道的是,該系統(tǒng)調(diào)用的庫(kù)中,最終是要調(diào)用到svc指令的,使cpu陷入svc異常,進(jìn)而跳轉(zhuǎn)到Linux Kernel中的el0_svc向量表中。
如下展示了系統(tǒng)調(diào)用進(jìn)入Linux Kernel后的具體流程:
el0_svc–> el0_svc_handler() --> el0_svc_common() --> invoke_syscall() --> syscall_fn(), syscall_fn指向系統(tǒng)調(diào)用tab表中的具體函數(shù)
4、總結(jié)
- 系統(tǒng)調(diào)用在Kernel中的map表,都在 kernel-4.19/include/uapi/asm-generic/unistd.h 中,表的名字是:sys_call_table,表中成員的示例如下:
- 系統(tǒng)調(diào)用函數(shù)的定義,都是以SYSCALL_DEFINEx的宏定義的,例如:
總結(jié)
以上是生活随笔為你收集整理的Linux Kernel中的系统调用分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: optee系统服务/service的实现
- 下一篇: [How TO]-如何编写Linux k