首先,进入到内核源码目录/usr/src/linux-2.6.34中,添加自己的系统调用号。
lyh@lyh:~$ cd /usr/src/linux-2.6.34/
系统调用号在unistd_32.h文件中定义。
内核中每个系统调用号都是
以“__NR_"开头的,在该文件中添加自己的系统调用号
lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/include/asm/unistd_32.h
#define __NR_pwritev 334
#define __NR_rt_tgsigqueueinfo 335
#define __NR_perf_event_open 336
#define __NR_recvmmsg 337
#define __NR_mycall 338
#ifdef __KERNEL__
#define NR_syscalls 339
在内核源文件中该行为#define NR_syscalls 338,在系统调用执行的过程中,system_call()函数会根据该值来对用户态进程的有效性进行检查。
如果这个号大于或等于NR_syscalls,系统调用处理程序终止。
所以应该将原来的#define NR_syscalls 338修改为#define NR_syscalls 339
其次,在系统调用表中添加相应的表项
(1)lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/kernel/syscall_table_32.S
ENTRY(sys_call_table)
.long sys_restart_syscall
.long sys_exit
………………(这里省略了部分)
.long sys_rt_tgsigqueueinfo
.long sys_perf_event_open
.long sys_recvmmsg
.long sys_mycall
(2)lyh@lyh:/usr/src/linux-2.6.34$ sudo vim
arch/h8300/kernel/syscalls.S
#include <linux/sys.h>
#include <asm/linkage.h>
……………………(这里省略了部分)
.long SYMBOL_NAME(sys_vmsplice)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_getcpu)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_mycall)
最后,实现系统调用服务例程。
系统调用服务例程函数名为"sys_xxx”
lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/kernel/sys_i386_32.c asmlinkage long sys_mycall(void)
{
printk("hello, world!\n mycall worked!\n");
}
其中,asmlinkage修饰符是gcc中一个特殊的标志,加了该修饰符的函数必须从堆栈中获取参数。
内核中所有系统调用的实现都使用这个修饰符。
接下来的任务就是重新编译内核了!注意:内核编译完了之后必须重启,否则已经添加的用户系统调用不能使用。
lyh@lyh:~$ sudo /usr/include/bits/syscall.h
#ifndef _SYSCALL_H
# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
#endif
#include <bits/wordsize.h>
#define SYS__sysctl __NR__sysctl
#define SYS_access __NR_access
………………(这里省略了部分)
#define SYS_vm86old __NR_vm86old
#define SYS_waitpid __NR_waitpid
#define SYS_mycall __NR_mycall
#endif
为了检验添加的系统调用是否成功,特编写下面的测试程序。
lyh@lyh:~/linux课程实验/系统调用$ vim test.c
#include <stdio.h>
#include <stdio.h>
#include <syscall.h>
#include <sys/types.h>
#define mycall() syscall(SYS_mycall)
int main()
{
mycall();
return 0;
}
lyh@lyh:gcc test.c -o test
lyh@lyh: ./test
这样一个简单的系统调用便添加成功了!。