我们載学习系统调用的时候应该基本都会在内核中添加自己的系统调用了。我再大体罗嗦一下:
一般我们常用的方法是在/arch/x86/include/asm/unistd_32.h下修改系统调用号,在/arch/x86/kernel/syscall_table_32.S /arch/x86/kernel/sys_i386_32.c
下修改系统调用服务例程。对于系统调用号的修改我们要按顺序添加系统调用号,否则会出现错误。如:
352 #define __NR_syncfs 344
353 #define __NR_sendmmsg 345
354 #define __NR_setns 346
355 #define __NR_mycall 347 //add this line
356 #ifdef __KERNEL__
357
358 #define NR_syscalls 348
我在355行添加了自己的系统调用,总的系统调用NR_syscalls就要加一。
然后在syscall_table_32.S添加新的系统调用的基址
347 .long sys_sendmmsg /* 345 */
348 .long sys_setns
349 .long sys_mycall //add this line
然后在内核/arch/x86/kernel/sys_i386_32.c中加入自己的系统调用。
以上都实现之后就需要重新编译内核,相信大多数人都不愿干漫长的工作。
现在对于系统调用的实现我们可以通过内核模块的方式实现。不用繁琐的编译内核了。
在模块里面还是要实现自己的系统调用函数。
接下来在初始化模块时,我们要做的工作是先保存系统调用表中原来位置的系统调用。
save=(int (*) (void)) (sys_call_table[__NR__xxx]);
sys_call_table[__NR__xxx] = (unsigned long ) sys_XXX /*此处把之前实现的系统调用放入系统调用表*/
在注销模块中,又要恢复原来的系统调用:即
sys_call_table[__NR__xxx] = (unsigned long ) save;
以上给出了主要实现步骤。使用模块添加系统调用一个明显的特点是我们的系统调用是动态实现的,当卸载模块后,我们的系统调用也就消失。
阅读(2333) | 评论(0) | 转发(0) |