Linux内核源码解析 | system call part 2

Linux内核源码解析 | system call part 2

摘要

  • 回顾: 应用程序如何调用 system call
  • 初始化 system calls table

2. 回顾

  • 应用程序必须首先将 对应的 system call 在 系统调用表中对应的编号 存入rax寄存器,然后以正确的顺序 将正确的system call参数值填充通用寄存器 rdi ,rsi,rdx ,rcx ,r8 中,并使用syscall指令进行实际的系统调用
  • syscall指令,系统 将跳入 存储在 MSR_LSTAR Model specific register(Long system target address register)中的地址,在该地址, 存有一个 system call 全局处理函数 entry_SYSCALL_64,
  • entry_SYSCALL_64 负责根据rax 寄存器的值 调用内核中对应的 system call hanler function.

3.初始化 system calls table

3.1 为什莫要 初始化 system calls table? 这个表是干什么的?

当在执行 entry_SYSCALL_64 时, entry_SYSCALL_64 需要根据rax中对应的 system call 的编号,调用对应的 system call handler function。但是Linux内核如何搜索该system call所对应系统调用处理程序的地址呢? Linux内核包含一个特殊的表,称为system calls table。系统调用表由sys_call_table数组表示,entry_SYSCALL_64 将通过该数组,找到 该system call 所对应的处理函数的地址,并调用该处理函数完成 system call。

3.2 如何初始化 system calls table

system calls table 由Linux内核中的sys_call_table数组表示,该数组在arch / x86 / entry / syscall_64.c源代码文件中定义。让我们看一下它的实现

asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
   
    [0 ... __NR_syscall_max] = &sys_ni_syscall,
    #include <asm/syscalls_64.h>
};
  • sys_call_table是长度为__NR_syscall_max + 1的数组,其中__NR_syscall_max宏表示给定体系结构的最大系统调用数。在 x86_64 体系结构下 共有 547个 系统调用(#define __NR_syscall_max 547),与之对应,在 系统调用表中也有相同数量的 system call
3.2.1 the sys_call_table array 的 类型 是什么?
  • sys_call_ptr_t 表示指向system call table的指针。它被定义为用于不返回任何内容且不接受参数的函数指针:
typedef void (*sys_call_ptr_t)(void);
3.2.2 初始化 sys_call_table array
  • 首先 数组中所有的元素,即 指向system call handler function的指针 指向了 sys_ni_syscall. sys_ni_syscall函数表示未实现的系统调用。 这跟 初始化 int 变量类似,仅仅是为了使该变量在内存空间中占有一个“位置”。 sys_ni_syscall 仅仅是一个返回 -errno 的函数:
asmlinkage long sys_ni_syscall(void)
{
   
    return -ENOSYS;   //ENOSY tell us  Function not implemented (POSIX.1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值