linux下增加系统调用
1).inculde/asm/unistd.h在这个文件中加入 #define_NR_testsyscall 191 2).are/i386/kernel/entry.s这个文件用来对指针数组初始化,在这个文件中增加一行: .long SYMBOL_NAME(_sys_tsetsycall) 将.rept NR_syscalls-190改为NR_SYSCALLS-191,然后重新奖励和运行新内核.
3).使用新的系统调用 在保证的C语言库中没有新的系统调用的程序段,自己建立其代码如下
#inculde _syscall0(int,testsyscall) main() { tsetsyscall(); } 在这里使用了_syscall0()宏指令,宏指令本身在程序中将扩展成名为syscall()的函数,它在main()函数内部加以调用. 在testsyscall()函数中, 预处理程序产生所有必要的机器指令代码,包括用系统调用参数值加载相应的cpu寄存器, 然后执行int 0x80中断指令. 3.利用内核模块添加系统调用 模块是内核的一部分,但是并没有被编译到内核里面去.它们被分别编译并连接成一组目标文件, 这些文件能被插入到正在运行的内核,或者从正在运行的内核中移走.内核模块至少有2个函数: int_module和cleanup_module.第一个函数是在把模块插入内核时调用的; 第二个函数则在删除该模块时调用.内核模块是内核的一部分,能访问所有内核资源.根据对linux系统调用机制的分析, 如果要增加系统调用,可以编写自己的函数来实现,然后在sys_call_table表中增加一项,使该项中的指针指向自己编写的函数, 就可以实现系统调用.下面用该方法实现在控制终端上打印“hello world” 的系统调用testsyscall(). 1)编写系统调用内核模块 #inculde(linux/kernel.h) #inculde(linux/module.h) #inculde(linux/modversions.h) #inculde(linux/sched.h) #inculde(asm/uaccess.h) #define_NR_testsyscall 191 extern viod *sys_call table[]; asmlinkage int testsyscall() { printf("hello worldn"); return 0; } int init_module() { sys_call_table[_NR_tsetsyscall]=testsyscall; printf("system call testsyscall() loaded successn"); return 0; } void cleanup_module() { } 2)使用新的系统调用#define #define_NR_testsyscall 191 _syscall0(int,testsyscall) main() { testsyscall(); } 3)编译内核模块并插入内核 编译内核的命令为:gcc -Wall -02 -DMODULE -D_KERNEL_-C syscall.c
-Wall通知编译程序显示警告信息;参数-02 是关于代码优化的设置, 内核模块优化; 参数-D_LERNEL通知头文件向内核模块提供正确的定义; 参数-D_KERNEL_通知头文件, 这个程序代码将在内核模式下运行.编译成功后将生成 syscall.0文件.使用insmod syscall.o命令将模块插入内核后即可使用增加的系统调用. 比较以上二种方法,笔者认为采用内核模块的方法较好.这种方法可省去编译新内核并用新内核重新 启动的麻烦,这一优点对于代码的调试是非常有价值的, 可以节省大量时间.
|
|||
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |