Friday, October 31, 2008

system call example (1)

参考文献:

Chapter 4, Linux kernel development second edition

深入LINUX内核:为你的LINUX增加一条系统调用

  充分利用LINUX开放源码的特性,我们可以轻易地对它进行修改,使我们能够随心所欲驾驭LINUX,完成一个真正属于自己的操作系统,这种感觉使无与伦比的,下面通过为LINUX增加一个系统调用来展示LINUX作为一个开放源码操作系统的强大魅力。
  首先,让我们简单地分析一下LINUX中与系统调用的相关的部分:
  LINUX的系统调用的总控程序是system_call,它是LINUX系统中所有系统调用的总入口,这个system_call是作为一个中断服务程序挂在中断0x80上,系统初始化时通过void init trap_init(void)调用一个宏set_system_ gate(SYSCALL_VERCTOR,&system_call)来对IDT表进行初始化,在0x80对应的中断描述符处填入system_call函数的地址,其中宏SYSCALL_VERCTOR就是0x80
  当发生一条系统调用时,由中断总控程序保存处理机状态,检查调用参数的合法性,然后根据系统调用向量在sys_call_table中找到相应的系统服务例程的地址,然后执行该服务例程,完成后恢复中断总控程序所保存的处理机状态,返回用户程序。
  系统服务例程一般定义于kernel/sys.c中,系统调用向量定义在include/asm-386/unistd.h中,而sys_call _table表则定义在arch/i386/kernel/entry.S文件里。
  现在我们知道增加一条系统调用我们首先要添加服务例程实现代码,然后在进行对应向量的申明,最后当然还要在sys_call_table表中增加一项以指明服务例程的入口地址。
  OK,有了以上简单的分析,现在我们可以开始进行源码的修改,假设我们需要添加一条系统调用计算两个整数的平方和,系统调用名为add2,我们需要修改三个文件:kernel/sys.c , arch/i386/kernel/entry.S include/asm-386/unistd.h
  1、修改kernel/sys.c ,增加服务例程代码:
  asmlinkage int sys_add2(int a , int b)
    
{
      
int c=0;
      
c=a*a+b*b;
      
return c;
    
}
  2、修改include/asm-386/unistd.h ,对我们刚才增加的系统调用申明向量,以使用户或系统进程能够找到这条系统调用,修改后文件如下所示:

  .... .....
  #define _NR_sendfile  
187
  #define _NR_getpmsg   
188
  #define _NR_putmsg    
189
  #define _NR_vfork    
190
  #define _NR_add2     191   /* 这是我们添加的部分,191即向量
*/
  3、修改include/asm-386/unistd.h , 将服务函数入口地址加入 sys_call_table,首先找到这么一段:

  .... .....
  
.long SYMBOL_NAME(sys_sendfile)
  
.long SYMBOL_NAME(sys_ni_syscall) /* streams 1 */
  
.long SYMBOL_NAME(sys_ni_syscall) /* streams 2 */
  
.long SYMBOL_NAME(sys_vfork) /*190 */
  
.rept NR_syscalls-190
  修改为如下:

  .... .....
  
.long SYMBOL_NAME(sys_sendfile)
  
.long SYMBOL_NAME(sys_ni_syscall) /* streams 1 */
  
.long SYMBOL_NAME(sys_ni_syscall) /* streams 2 */
  
.long SYMBOL_NAME(sys_vfork) /*190 */
  .long SYMBOL_NAME(sys_add2) <=我们的系统调用

  .rept NR_syscalls-191 <=190改为191
  
OK,
大功告成,现在只需要重新编译你的LINUX内核,然后你的LINUX就有了一条新的系统调用int add2(int a, int b)

urg

No comments: