免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3274 | 回复: 2
打印 上一主题 下一主题

2.6.37.3内核添加系统调用的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-04-05 00:08 |只看该作者 |倒序浏览
本帖最后由 licyuan 于 2011-04-05 00:25 编辑

我添加一个系统调用,照着书上的步骤,最后用用户程序测试的时候发现调用失败,返回结果为-1,errno值为38,不知道问题出在哪儿,请大牛们帮忙看下


系统版本是 Linux ubuntu 2.6.37.3 #11 SMP Mon Apr 4 06:47:38 PDT 2011 x86_64 GNU/Linux


所修改的内核版本也是2.6.37.3

更改的源码文件分别是下列几个:

1、新建一个文件arch/x86/kernel/ff_get_ctx.c,其中实现返回当前进程的ctx的功能(ctx记录了进程被schedule的次数,是在task_struct中自己添加的一个成员,而且已经写了一个模块测试是没有问题的)
内容如下
  1. #include<linux/linkage.h>
  2. #include<linux/kernel.h>
  3. #include<linux/sched.h>
  4. asmlinkage unsigned long sys_ff_get_ctx(void){
  5.         printk(KERN_WARNING"Enter syscall ff_get_ctx!\n");
  6.         return (current->ff_ctx);
  7. }
复制代码
2、修改arch/x86/include/asm/unistd_32.h, 加上自己定义的系统调用号,并更改NR_syscalls宏
  1. #define __NR_fanotify_mark        339
  2. #define __NR_prlimit64                340

  3. /*        Add new syscall
  4. */
  5. #define __NR_ff_get_ctx                341

  6. #ifdef __KERNEL__

  7. /*        Modify syscall_table size
  8.         Original:#define NR_syscalls 341
  9. */
  10. #define NR_syscalls 342
复制代码
3、修改arch/x86/kernel/syscall_table_32.S,在其最后加上
  1.         .long sys_fanotify_mark
  2.         .long sys_prlimit64                /* 340 */
  3.         .long sys_ff_get_ctx        /*341        newly added syscall*/
复制代码
4、include/linux/syscalls.h中添加
  1. /*        Newly added syscall declaration
  2. */
  3. asmlinkage unsigned long sys_ff_get_ctx(void);
复制代码
5、修改arch/x86/kernel/Makefile,在obj-y中加入自定义的目标
  1. obj-y                        += tsc.o io_delay.o rtc.o
  2. obj-y                        += pci-iommu_table.o
  3. obj-y                        += resource.o

  4. #        Add newly syscall obj-file
  5. obj-y                        += ff_get_ctx.o

复制代码
然后重新编译内核并加载,写一个用户程序测试一下
  1. #include<stdio.h>
  2. #include<linux/unistd.h>
  3. #include<errno.h>
  4. #include<sys/syscall.h>

  5. #define __NR_ff_get_ctx                341

  6. int main(){
  7.         unsigned long t=syscall(__NR_ff_get_ctx);
  8.         if(t==-1){
  9.                 printf("Error occurs. errno=%d\n",errno);
  10.         }
  11.         else{
  12.                 printf("The ctx of this process is:\t%ld\n",t);
  13.         }

  14.         return 0;
  15. }
复制代码
但是结果却是  Error occurs. errno=38  ,即调用失败,查了一下errno 38的定义,Function not implemented,函数没有实现,请问下大家这是怎么回事呢?
在内核编译生成的System.map文件中已经有   ffffffff810142c0 T sys_ff_get_ctx     这一项了,说明这个符号已经在内核中,但是却没有与实现代码联系起来 ,现在怀疑我的系统是64位的,系统调用机制可能和32位的有些不同,但是还没有找到相关的资料,不知道是神马原因,希望有高人解答,不甚感激!

论坛徽章:
0
2 [报告]
发表于 2011-04-06 10:32 |只看该作者
arch/x86/include/asm/unistd_32.h
arch/x86/kernel/syscall_table_32.S
这两个文件看上去会有64位版本,你修改一下64位的试试吧

论坛徽章:
0
3 [报告]
发表于 2011-04-07 19:20 |只看该作者
回复 2# marsbible


    恩,谢谢   这个问题我已经解决了,主要是以下两步

1、在arch/x86/include/asm/unistd_64.h 中添加自己的系统调用号
  1. #define __NR_XXXXX    my_syscall_num
  2. __SYSCALL(__NR_XXXX,sys_XXXX)
复制代码


2、在/kernel下添加一个文件abcd.c,定义自己的系统调用
  1. asmlinkage long sys_XXXX(){

  2. //....code here....

  3. return ret_num;
  4. }
复制代码

在/kernel下的Makefile中加入自己的生成目标
obj-y += abcd.o


然后就是编译内核并加载了

用户态程序用   syscall(my_syscall_num, args....)来调用即可


以上是64位的系统调用的方法
32位的系统调用
是需要在arch/x86/include/asm/unistd_32.h和arch/x86/kernel/syscall_table_32.S中添加对应的项,然后用可以int 0x80调用

以上两类系统调用我已经试验成功了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP