博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
系统调用之sys_call_table(系统调用表)
阅读量:2492 次
发布时间:2019-05-11

本文共 2822 字,大约阅读时间需要 9 分钟。

sys_call_table中保存了系统调用的处理地址,该表的初始化过程非常巧妙。

系统调用程序system_call会查找系统调用表以获得系统调用号对应的系统调用,并执行。

sys_call_table

初始化sys_call_table的代码
// 定义位置:arch/x86/kernel/syscall_32.c#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ;#include 
#undef __SYSCALL_I386#define __SYSCALL_I386(nr, sym, compat) [nr] = sym,typedef asmlinkage void (*sys_call_ptr_t)(void);extern asmlinkage void sys_ni_syscall(void);// sys_call_table是一个数组,其值为typedef void (*sys_call_ptr_t)(void)类型的函数指针 __visible const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { /* * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ // 先对表中所有 __NR_syscall_max+1 项初始化为指向 sys_ni_syscall 的函数,该函数只返回 -ENOSYS,表示该系统调用未实现 [0 ... __NR_syscall_max] = &sys_ni_syscall,// syscalls_32.h是在编译时生成的#include
};

代码分析

头文件#include <asm/syscalls_32.h>

该文件是在编译时生成的。编译内核的时候,当执行/arch/x86/syscalls/Makefile编译规则时,该文件会执行/arch/x86/syscalls/syscalltbl.sh,该脚本将同目录下的syscall_32.tbl文件作为输入,然后生成文件arch/x86/include/generated/asm/syscalls_32.h,这个文件正是sys_call_table定义中包含的文件。

  • syscall_32.tbl的部分代码如下(其中定义了系统调用号及系统调用):
## 32-bit system call numbers and entry vectors## The format is:# 
## The abi is always "i386" for this file.#0 i386 restart_syscall sys_restart_syscall1 i386 exit sys_exit2 i386 fork sys_fork stub32_fork3 i386 read sys_read4 i386 write sys_write5 i386 open sys_open compat_sys_open6 i386 close sys_close
  • syscalltbl.sh代码如下:
#!/bin/shin="$1"out="$2"grep '^[0-9]' "$in" | sort -n | (    while read nr abi name entry compat; do	abi=`echo "$abi" | tr '[a-z]' '[A-Z]'`	if [ -n "$compat" ]; then	    echo "__SYSCALL_${abi}($nr, $entry, $compat)"	elif [ -n "$entry" ]; then	    echo "__SYSCALL_${abi}($nr, $entry, $entry)"	fi    done) > "$out"

in和out分别代表的就是syscall_32.tbl和syscalls_32.h文件的路径。脚本读取syscall_32.tbl内容,然后构造语句__SYSCALL_abi(nr, entry,entry)"。

  • syscalls_32.h中的生成的部分内容如下:
__SYSCALL_I386(0, sys_restart_syscall, sys_restart_syscall)__SYSCALL_I386(1, sys_exit, sys_exit)__SYSCALL_I386(2, sys_fork, stub32_fork)__SYSCALL_I386(3, sys_read, sys_read)__SYSCALL_I386(4, sys_write, sys_write)__SYSCALL_I386(5, sys_open, compat_sys_open)__SYSCALL_I386(6, sys_close, sys_close)__SYSCALL_I386(7, sys_waitpid, sys32_waitpid)__SYSCALL_I386(8, sys_creat, sys_creat)__SYSCALL_I386(9, sys_link, sys_link)__SYSCALL_I386(10, sys_unlink, sys_unlink)__SYSCALL_I386(11, sys_execve, stub32_execve)...
sys_call_table的展开

__SYSCALL_I386 是一个宏定义:#define __SYSCALL_I386(nr, sym, compat) [nr] = sym

const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {    [0 ... __NR_syscall_max] = &sys_ni_syscall,    [0] = sys_restart_syscall,    [1] = sys_exit,    [2] = sys_fork,    [3] = sys_read,    //...};

系统调用处理程序system_call执行call *sys_call_table(,%rax,4),即可转入系统调用函数进行真正处理。

转载地址:http://wwerb.baihongyu.com/

你可能感兴趣的文章
OCO订单(委托)
查看>>
学习笔记_vnpy实战培训day06
查看>>
回测引擎代码分析流程图
查看>>
Excel 如何制作时间轴
查看>>
股票网格交易策略
查看>>
matplotlib绘图跳过时间段的处理方案
查看>>
vnpy学习_04回测评价指标的缺陷
查看>>
ubuntu终端一次多条命令方法和区别
查看>>
python之偏函数
查看>>
vnpy学习_06回测结果可视化改进
查看>>
读书笔记_量化交易如何建立自己的算法交易01
查看>>
设计模式03_工厂
查看>>
设计模式04_抽象工厂
查看>>
设计模式05_单例
查看>>
设计模式06_原型
查看>>
设计模式07_建造者
查看>>
设计模式08_适配器
查看>>
设计模式09_代理模式
查看>>
设计模式10_桥接
查看>>
设计模式11_装饰器
查看>>