LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1365|回复: 10

请教添加系统调用的方法,由于是作业,请哪位老大一定看看

[复制链接]
发表于 2006-2-25 22:48:00 | 显示全部楼层 |阅读模式
我的内核2.6.15(gentoo-2.6.15-r3)
书上有添加内核的方法,但是平台是在2.4内核上,我觉得2.6应该差不多。但是弄了半天一直不对啊,帮我看看啊!
比如添加一个最简单的系统调用sillysyscall
我的步骤:
step 1:
    编辑unistd.h添加系统调用号。
    由于有两个unistd.h,系统的unistd.h在/usr/include/asm/里,内核的unistd.h在/usr/src/linux/include/asm里,我还不清楚到底该改那一个,于是尝试了3次,分别改,全改,好象结果是一样的。
    添加:
  1. #define __NR_sillysyscall        295
复制代码


step 2:
    在syscall table中添加一个值。
    编辑/usr/src/linux/arch/i386/kernel/syscall_table.S,添加
  1.         .long sys_sillysyscall
复制代码


step 3:
    实现sillycall
    编辑/usr/src/linux/kernel/sys.c
  1. asmlinkage long sys_sillysyscall(long arg0)
  2. {
  3.         return arg0;       //直接传回参数
  4. }
复制代码


然后从新编译内核,用新内核启动写个用户态程序测试:

  1. //c file : test.c
  2. #include<linux/unistd.h>

  3. _syscall1(long,sillysyscall,long,arg0)
  4. int main()
  5. {
  6.         int s;
  7.         s=sillysyscall(3);
  8.         printf("s=%d\n",s);
  9.         return 0;
  10. }
复制代码
  1. woodenapple@nax ~/Gcc/test/ $ gcc -o test test.c
  2. woodenapple@nax ~/Gcc/test/ $ ./test
  3. s=-1                      [color=red]结果不对,-1是出错的意思吗?[/color]
  4. woodenapple@nax ~/Gcc/test/ $
复制代码



实在是郁闷啊,这个是作业,我不敢怠慢啊,就请哪位告诉小弟一声怎么搞,哪里有问题,应该也不难。这里先谢谢了
发表于 2006-2-25 23:00:42 | 显示全部楼层
新内核编译了吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-2-25 23:32:54 | 显示全部楼层
当然编译了啊,而且测试程序是在新内核里运行的
回复 支持 反对

使用道具 举报

发表于 2006-2-26 01:35:29 | 显示全部楼层
下了一个 2.6.15 的内核,看了一下,最后一个系统调用号是293,如果你再加一个,似乎应该是294号而不是295号
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-2-26 12:26:35 | 显示全部楼层
由于两个unistd.h内容不同,我干脆就把两个系统调用使用的同一个调用号,这个不知道有没有问题


我的/usr/src/linux/include/asm-i386/unistd.h:
  1. ......
  2. #define __NR_inotify_init       291
  3. #define __NR_inotify_add_watch  292
  4. #define __NR_inotify_rm_watch   293

  5. #define NR_syscalls 294
  6. [color=blue]#define __NR_sillysyscall         295[/color]         [color=red]//添加的系统调用[/color]

  7. /*
  8. * user-visible error numbers are in the range -1 - -128: see
  9. * <asm-i386/errno.h>
  10. */
  11. #define __syscall_return(type, res) \
  12. ......
复制代码

我的/usr/include/asm/unistd.h:
  1. ......
  2. #define __NR_add_key            286
  3. #define __NR_request_key        287
  4. #define __NR_keyctl             288

  5. #define NR_syscalls 289

  6. [color=blue]#define __NR_sillysyscall         295[/color]
  7. [color=red]//添加的系统调用,由于在内核的unistd.h中添加的是295号,                                                                                             //我就把这里本来应该是290号的也改成了295号,不知道能不能这样做?
  8. //另外,这里的289号(上面的294号)NR_syscalls是什么?
  9. //是不是应该把添加的系统调用放到NR_syscalls前面?[/color]


  10. /*
  11. * user-visible error numbers are in the range -1 - -128: see
  12. * <asm-i386/errno.h>
  13. */
  14. #define __syscall_return(type, res) \
  15. ......
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-2-26 12:52:34 | 显示全部楼层
郁闷死了,内核都编译了十几次了,每次返回都是-1,救命啊
回复 支持 反对

使用道具 举报

发表于 2006-2-26 14:31:13 | 显示全部楼层
果然是系统调用号搞错了,NR_syscalls 表示系统调用的个数,294表示有294个系统调用,标号从0开始,所以最后一个系统调用号是293,那么新加的系统调用号应该是294。其实这个宏在386体系下并没有使用。

想想凭什么你定义 __NR_sillysyscall         295,内核就能找到相应的处理函数? 还不是根据295这个数字在sys_call_table里面找,而sys_call_table的最大下标是294,不是295,自然也就出错了。具体原因还可参考arch/${arch}/kernel/entry.S 中 system_call 那一段
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-2-26 16:07:25 | 显示全部楼层
谢谢rickxbx啦,果然是这个原因。惭愧啊,还是应该多看看代码,一些书上只有方法,真正的原理还得看程序才看得出来的啊
回复 支持 反对

使用道具 举报

发表于 2006-12-22 13:27:27 | 显示全部楼层
哈哈.lz是哪个学校的,怎么我们老师也是叫交这个作业啊。
我的还没有做,呵呵。时间不多了。
回复 支持 反对

使用道具 举报

发表于 2006-12-22 15:42:47 | 显示全部楼层
你的是什么书呢???
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表