添加系统调用实验步骤
首先,进入到内核源码目录/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>
#include
<asm/unistd.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
<linux/unistd.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
这样一个简单的系统调用便添加成功了!