CentOS6.2 自定义系统调用

  我使用的是CentOS6.2

1.下载内核

  以linux-2.6.39.tar.bz2为例

2.解压缩

  解压缩至/usr/src/kernels/linux-2.6.39

3.添加函数到内核映像中

   系统调用必须编译到内核映像中去,此例放入linux-2.6.39/kernels/sys.c,也可以放入其他的.c文件,主要是功能联系相关

  观察sys.c文件,找一个函数举例:

  

 1 SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
 2 {
 3     int errno;
 4     char tmp[__NEW_UTS_LEN];
 5 
 6     if (!capable(CAP_SYS_ADMIN))
 7         return -EPERM;
 8     if (len < 0 || len > __NEW_UTS_LEN)
 9         return -EINVAL;
10 
11     down_write(&uts_sem);
12     errno = -EFAULT;
13     if (!copy_from_user(tmp, name, len)) {
14         struct new_utsname *u = utsname();
15 
16         memcpy(u->domainname, tmp, len);
17         memset(u->domainname + len, 0, sizeof(u->domainname) - len);
18         errno = 0;
19     }
20     up_write(&uts_sem);
21     return errno;
22 }

SYSCALL_DEFINE2只是一个宏,数字2表示该函数有2个参数,宏展开之后如下:

asmlinkage long sys_setdomainname(char __user* name, int len)

asmlinkage是限定词,这是一个编译指令,通知编译器通过栈传递函数参数,默认的是通过寄存器传参,所有的系统调用都需要这个限定词。

 

在sys.c文件中,加入自己写的系统调用:

 

 1 asmlinkage int sys_sumtest(int number)
 2 
 3 {
 4 
 5  int i=0,sum=0;
 6 
 7  printk("<0>""这是添加的系统调用\n");
 8 
 9  while(i<=number)
10 
11   sum+=i++;
12 
13  return sum;
14 
15 }

 

 

 

 

4.注册系统调用号

 

 

在  linux-2.6.39/arch/x86/include/unistd_32.h 头文件中注册系统调用号

 

实例代码:

 

#define __NR_sumtest    333

 

5.填写系统调用表

 

 linux-2.6.39/arch/x86/kernel/syscalls_table_32.S,在syscall_table(系统调用表)中对应于系统调用号的位置,填写系统调用函数。

 

实例代码:

 

ENTRY(sys_call_table)

 

    .long sys_restart_syscall   

 

    .long sys_exit

 

    .......

    .......

 

    .long sys_syncfs

 

    .long sys_sumtest    //333 本次添加的系统调用函数

 

 

6.编译、安装内核

 

   另外一篇文章有详细过程

 

7.重启,使用新内核引导开机,测试系统调用

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 int main(int argc,char ** argv)
 5 {
 6     int temp;
 7     int src=5;
 8     if(argc>2)
 9         printf("argument error!\n");
10     else
11     {
12         if(argc==1)
13             temp=syscall(345,src);
14         else
15         {
16             src=atoi(argv[1]);
17             temp=syscall(345,src);
18         }
19         printf("sum of 1 to %d is tmp=%d\n",src,temp);
20     }
21     return 0;
22 }

 

 

 

posted @ 2012-06-17 16:44  Hakunamatata-  阅读(875)  评论(0编辑  收藏  举报