花了一天半的时间,终于是把linux系统调用这个问题给解决掉了。这里记下一些我所遇到的问题以及解决办法等等。
首先在做这个问题之前必须保证自己的linux环境是一个干净的,没有其他人修改过该系统调用表。 之前我一直都是用机房所提供的RedHat9(2.4.20-8)版本上测试,修改系统调用表之后始终没有成功启动系统…那么如何才能保证你所使用的是一个干净的Linux环境呢?这个时候就可以参考到我之前写的一篇博客redhat9(内核版本2.4.20-8)编译内核到版本(2.4.26)
拿到一个新的Linux环境之后,就可以开始我们这次的主题了^_^。我新编译的内核版本是linux-2.4.22,之前的版本是linux-2.4.20-8。因此各位同学要自己按照自己的新内核版本进入相应的文件夹…操作步骤如下(再啰嗦一句,由于使用了系统调用,编译和执行程序时,用户都应该是超级用户身份。):
在/usr/src/linux-2.4.22/arch/i386/kernel/entry.S文件中的系统调用入口表中,找到某个空项:
.long SYMBOL_NAME(sys_ni_syscall) 修改为新加系统调用的入口项:
.long SYMBOL_NAME(sys_my_call) /* 254——系统调用号 */
记住系统调用号(在系统调用入口表中的第几个入口),例如254。
在/usr/src/linux-2.4.22/kernel/sys.c中添加实现系统调用my_call()的代码段:
asmlinkage int sys_my_syscall() /*函数名为sys_my_syscall*/ { /*这个函数的唯一作用是向屏幕上输出一句话*/ printk(“Hello, now we are in the kernel\n”); return 0; }重新编译内核,依次输入以下命令:
cd /usr/src/linux-2.4.22
make clean
make dep
make bzImage
make install编译完成上面步骤后,需要重启linux内核,使修改后的linux内核得以运行。
编写c程序使用新的系统调用
#define __NR_my_syscall 254 int errno; /* 这里告诉编译器,my_syscall系统调用的编号是254 */ #include <linux/unistd.h> _syscall0(int,my_syscall) /* 这里告诉编译器,请把my_syscall作为一个系统调用来编译,而不是普通函数*/ main() { my_syscall(); /* 在main函数里面使用了这个系统调用 */ }最后就是编译、执行刚才编写的c程序,分别输入以下命令:
gcc -o test_my_syscall test_my_syscall.c
./test_my_syscall步骤无误的话,就可以通过键入dmesg命令回车,看到自己写入系统表的内容显示在系统启动信息的最下一行了~~
Linux (RedHat 9) 添加系统调用正式完成。恭喜,恭喜!你不仅编译了内核,而且尝试着修改并启动了新的内核,还在这个内核上增加了一个系统调用。能够把这些步骤全都做完是相当不容易的。
本文详细介绍了在Linux环境下新增系统调用的过程,包括环境准备、内核修改与编译、编写及执行用户空间调用程序等关键步骤。
329

被折叠的 条评论
为什么被折叠?



