在2.6的时代,写一个linux的系统调用的步骤是这样的:
- 编写实际操作函数
- 在linux/include/asm-i386/unistd.h中添加宏定义
#define __NR_myfunctioin 399
- 在linux/arch/i386/kernel/entry.S中添加
.long SYMBOL_NAME(myfunction)
- 编译内核
- 通过_syscall[1-6](type, name, type, arg1)来调用
而最新版本的kernel对应位置找不到相应的宏定义文件了
unistd.h文件修改为分别对32和64位的版本的引用,并分别放置在了/arch/x86/include/uapi/asm/unistd_[32|64|x32].h,arm的放置在了/arch/arm/uapi/asm/unistd.h中,其它架构的也差不多的位置
另外有些文件修改为了__SYSCALL(n, call)方式定义
entry.S文件也中sys_call_table的相关定义也放置在了syscall.h文件中,将原来的汇编并修改为C数组的定义方式
__SYSCALL是宏
#define __SYSCALL(n, call) [nr] = (call),
#define __SYSCALL_XX(n, sym, compat)
另外添加了sys_call_table[NR_syscalls]数组
void *sys_call_table[NR_syscalls] = {
[0 ... NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h>
}
目前,kernel中存在直接使用宏定义数字和__SYSCALL两种方式方式来定义系统调用的。