本文基于Linux 2.4.26内核,GCC 3.2.2添加系统调用mycall(int num)
增加系统调用只修改/usr/src/linux-2.4.29/include/asm-i386/unistd.h和arch/i386/kernel/entry.S,系统调用函数一般在kernel/sys.c中,这里把增加的系统调用代码也加入这个文件中。
1.修改kernel/sys.c文件,加入自己的系统调用代码,同参考文献(见文后地址)中,
asmlinkage int sys_mycalll(int num)
{
printk("This is added by yan/n");
return num;
}
往内核输出一句话,然后返回参数值。asmlinkage表示通过堆栈递参数。
2.然后把sys_mycall(int )的入口地址添加到sys_call_table表中。该表依次存储所有系统调用的入口地址。
修改前为:
.long SYMBOL_NAME(sys_ni_syscall) /* sys_set_tid_address这是第258个系统调用* /
.rept NR_syscalls-(.-sys_call_table)/4
.long SYMBOL_NAME(sys_ni_syscall)
修改后:
.long SYMBOL_NAME(sys_ni_syscall) /* sys_set_tid_address * /
.long SYMBOL_NAME(sys_mycall) /*这是增加的第259个系统调用*/
.rept NR_syscalls-(.-sys_call_table)/4-1 /*这里重复次数减少1*/
.long SYMBOL_NAME(sys_ni_syscall)
3.把增加的sys_call_table表项所对应的向量,在include/asm-i386/unistd.h中进行必要申明,以供用户进程和其他系统进程查询或调用:
#define __NR_exit_group 252
#define __NR_mycall 259 /*这是增加的第259个系统调用*/
然后编译内核make bzImage,并用生成的新内核启动系统。
覆盖原有的内核 cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.26
cp System.map /boot/System.map-2.4.26
4.测试程序(test.c)如下:
#include <stdio.h> #include <asm/unistd.h> int errno; _syscall1(int,mycall,int,num);//_syscall1表示该系统调用有1个参数,同样_syscall2表示2个调用参数 int main() { int i,j; printf("Please input a number/n"); scanf("%d",i); j=mycall(i); printf("The value returned from the kernel is %d/n",j); }
然后执行命令
dmesg | tail
看到输出的内容
This is added by yan