歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 解讀Linux操作系統內核源碼的好方法(3)

解讀Linux操作系統內核源碼的好方法(3)

日期:2017/2/25 10:37:02   编辑:Linux教程

解讀Linux操作系統內核源碼的好方法(3)

3. 把增加的 sys_call_table 表項所對應的向量,在include/asm-386/unistd.h

  中進行必要申明,以供用戶進程和其他系統進程查詢或調用:

  增加後的部分 /usr/src/linux/include/asm-386/unistd.h 文件如下:

  ... ...

  #define __NR_sendfile 187

  #define __NR_getpmsg 188

  #define __NR_putpmsg 189

  #define __NR_vfork 190

  /* add by I */

  #define __NR_addtotal 191

  4.測試程序(test.c)如下:

  #include

  #include

  _syscall1(int,addtotal,int, num)

  main()

  {

  int i,j;

  do

  printf("Please input a number\n");

  while(scanf("%d",&i)==EOF);

  if((j=addtotal(i))==-1)

  printf("Error occurred in syscall-addtotal();\n");

  printf("Total from 0 to %d is %d \n",i,j);

  }

  對修改後的新的內核進行編譯,並引導它作為新的操作系統,運行幾個程序後可以發現一切正常;在新的系統下對測試程序進行編譯(*注:由於原內核並未提供此系統調用,所以只有在編譯後的新內核下,此測試程序才能可能被編譯通過),運行情況如下:

  $gcc -o test test.c

  $./test

  Please input a number

  36

  Total from 0 to 36 is 666

  可見,修改成功;

  而且,對相關源碼的進一步分析可知,在此版本的內核中,從/usr/src/linux/arch/i386/kernel/entry.S

  文件中對 sys_call_table 表的設置可以看出,有好幾個系統調用的服務例程都是定義在/usr/src/linux/kernel/sys.c

  中的同一個函數:

  asmlinkage int sys_ni_syscall(void)

  {

  return -ENOSYS;

  }

  例如第188項和第189項就是如此:

  ... ...

  .long SYMBOL_NAME(sys_sendfile)

  .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */

  .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */

  .long SYMBOL_NAME(sys_vfork) /* 190 */

  ... ...

  而這兩項在文件 /usr/src/linux/include/asm-386/unistd.h 中卻申明如下:

  ... ...

  #define __NR_sendfile 187

  #define __NR_getpmsg 188 /* some people actually want streams */

  #define __NR_putpmsg 189 /* some people actually want streams */

  #define __NR_vfork 190

  由此可見,在此版本的內核源代碼中,由於asmlinkage int sys_ni_syscall(void) 函數並不進行任何操作,所以包括 getpmsg,

  putpmsg 在內的好幾個系統調用都是不進行任何操作的,即有待擴充的空調用;

  但它們卻仍然占用著sys_call_table表項,估計這是設計者們為了方便擴充系統調用而安排的;

  所以只需增加相應服務例程(如增加服務例程getmsg或putpmsg),就可以達到增加系統調用的作用。

Copyright © Linux教程網 All Rights Reserved