日期:2014-05-16  浏览次数:20748 次

linux内核--添加系统调用

1、目的:

在现有的系统中添加一个不用传递参数的系统调用。这个系统调用的功能是实现遍历系统中的所有进程。实验主要内容:

  • 添加系统调用的名字
  • 利用标准 C 库进行包装
  • 添加系统调用号
  • 在系统调用表中添加相应表项
  • sys_mysyscall 的实现
  • 编写用户态测试程序

2、步骤:

a)安装依赖库:

[plain] view plaincopy
  1. sudo apt-get install libncurses5-dev //如果没有ncurses库,则安装  

b)下载内核源代码(以3.6.8版本为例):

linux-3.6.8.tar.bz2文件,放到/home目录即可。

c)解压内核源代码:

[plain] view plaincopy
  1. #su //输入密码,用户权限改为root权限。或用sudo命令  
  2. #mv linux-3.6.8.tar.bz2 ~ //把内核代码文件移到主目录。  
  3. # cd ~  //进入主目录  
  4. # tar jxvf linux-3.6.8.tar.bz2 //解压内核包,生成的内核源代码放在linux.3.6.8目录中  
  5. # cd linux-3.6.8  



d)修改内核的系统调用库函数:

Ubuntu12.04(可不用修改):
[plain] view plaincopy
  1. /usr/include/asm-generic/unistd.h  
Kernel 3.6.8中要修改:
[plain] view plaincopy
  1. include/asm-generic/unistd.h  
进入后修改如下:
其中223号系统调用在syscall_table中没有使用(unused),所以可以修改为我们的调用
[cpp] view plaincopy
  1. /* mm/fadvise.c */  
  2. /* 
  3. #define __NR3264_fadvise64 223 
  4. __SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64) 
  5. */  
  6. #define __NR_rksyscall 223  
  7. __SYSCALL(__NR_rksyscall, sys_rksyscall)  


添加系统调用号之后,系统才能根据这个号,作为索引,去找 syscall_table 中的相应表项。
所以,接下来的一步就是:

e)在系统调用表中添加或修改相应表项

在上面步骤中解压出来的内核源代码包中进行修改相关函数:
进入下列目录:
[plain] view plaincopy
  1. arch/x86/kernel/syscall_table_32.S  
修改编号223对应的代码段:
[cpp] view plaincopy
  1. # 222 is unused  
  2. # 223 is used now  
  3. 223 i386 mysyscall sys_rksy