Linux内核系统调用的实现-主要逻辑

1 中断处理程序

1.1 以x86架构为例

int80中断处理程序中, 根据系统调用号, 调用系统调用表中对应的系统调用

大于等于4.17内核时, 所有的系统调用都只使用一个参数struct pt_regs, 该参数中保存了处理器状态和中断发生时相关寄存器的值, 系统调用具体的参数就保存在寄存器中

do_syscall_64()
 |-> regs->ax = sys_call_table[nr](regs); 

小于4.17时系统调用使用6个参数, 其实就是把struct pt_regs中存放系统调用参数的寄存器值传给了具体的系统调用

do_syscall_64()
 |-> regs->ax = sys_call_table[nr](regs->di, regs->si, regs->dx, 
                     regs->r10, regs->r8, regs->r9);

可以看到, 不管是哪个系统调用, 在中断处理程序中调用系统调用时传入的参数都一样(尽管每个系统调用的参数不尽相同), 具体的分析可以参考这篇文章

2 系统调用表

2.1 系统调用表的初始化

x86的系统调用表定义在/arch/x86/entry/syscall_64.c中, 初始化过程也很简单, 就是把系统调用的函数赋值给系统调用表对应的项中, 最终,sys_call_table数组中的每个元素都将指向对应的系统调用函数

asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
	[0 ... __NR_syscall_max] = &sys_ni_syscall,
    [1] = sys_write,
    [2] = sys_open,
    [3] = sys_close,
};

2.2 系统调用号和系统调用的名字

不同架构的系统调用号可能不一样, 例如x86

__SYSCALL_COMMON(1, sys_write, sys_write)
__SYSCALL_COMMON(2, sys_open, sys_open)
__SYSCALL_COMMON(3, sys_close, sys_close)
__SYSCALL_COMMON(4, sys_newstat, sys_newstat)
__SYSCALL_COMMON(5, sys_newfstat, sys_newfstat)

arm64

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)
#define __NR_write 64
__SYSCALL(__NR_write, sys_write)
#define __NR_readv 65
__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
#define __NR_writev 66
__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
#define __NR_pread64 67
__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
#define __NR_pwrite64 68
__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)

3 具体系统调用的实现

可以参考这篇文章

4 compat兼容系统调用

compat系统调用是为了向后兼容旧版Linux内核而设计的一组系统调用,可以在较新的Linux内核上运行旧版应用程序。这些系统调用具有与旧版Linux内核相同的接口和语义,使得旧版应用程序可以在新版Linux内核上运行而无需进行修改。

大多数的compat系统调用都是直接使用正常的系统调用, 个别的系统调用需要把参数转换一下

具体可以参考这篇文章

参考资料

https://elixir.bootlin.com/linux/v4.19.275/source/arch/x86/entry/syscall_64.c
https://elixir.bootlin.com/linux/v4.2.8/source/include/uapi/asm-generic/unistd.h#L200
https://elixir.bootlin.com/linux/v4.19.274/source/arch/x86/entry/common.c#L293
https://elixir.bootlin.com/linux/v4.19.274/source/arch/x86/entry/entry_64.S#L242
https://elixir.bootlin.com/linux/v4.16.18/source/arch/x86/entry/common.c#L269
ARM64系统中兼容系统调用表compat_sys_call_table的定义和初始化
简要分析Linux 4.19内核ARM64架构系统调用(syscall)的定义
gcc x86_64中调用函数时多传了几个参数会发生什么

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值