(一):添加一個系統調用

應用不能訪問內核的內存空間,為了應用和內核交互信息,內核提供一組接口,通過這組接口,應用可以發送請求,內核可以響應處理該請求,這組接口就是系統調用。 關於內核系統調用的實現查看本博客中這篇文章: http://blog.csdn.net/shallnet/article/details/47113753 本文章以x86-32為例:

$ uname -a  
Linux localhost 2.6.32 #1 SMP Sat Jun 13 23:55:06 CST 2015 i686 i686 i386 GNU/Linux  

第一步,在系統調用表中加入一個表項,表中為每一個有效的系統調用指定了惟一的系統調用號。系統調用表位於arch/x86/kernel/syscall_table_32.S文件中,在該文件中最後一行添加自己的系統調用表項,如下:

......  
.long sys_preadv  
.long sys_pwritev  
.long sys_rt_tgsigqueueinfo     /* 335 */  
.long sys_perf_event_open  
.long sys_shallnet  

雖然沒有明確指定編號,但該系統調用已經按次序分配了337這個系統調用號,接下來就應該添加系統調用號。 第二步,添加系統調用號。在Linux中,每個系統調用被賦予一個系統調用號。這樣,通過這個獨一無二的號就可以關聯繫統調用。當用戶空間的進程執行一個系統調用的時候,這個系統調用號就被用來指明到底是要執行哪個系統調用。在文件arch/sh/include/asm/unistd_32.h該列表中加入一行#define __NR_shallnet 337 :

......  
#define __NR_inotify_init1 332  
#define __NR_preadv 333  
#define __NR_pwritev 334  
#define __NR_rt_tgsigqueueinfo 335  
#define __NR_perf_event_open 336  
  
#define __NR_shallnet   337  
  
//#define NR_syscalls 337  
#define NR_syscalls 338  
......  

在內核源文件中該行為#define NR_syscalls 337,在系統調用執行的過程中,system_call()函數會根據該值來對用戶態進程的有效性進行檢查。如果這個號大於或等於NR_syscalls,系統調用處理程序終止。所以應該將原來的#define NR_syscalls 337修改為#define NR_syscalls 338。

第三步,實現shallnet系統調用。在文件kernel/sys.c最後添加如下函數:

SYSCALL_DEFINE0(shallnet)SYSCALL_DEFINE1(shallnet, int, arg)  
{  
    printk(KERN_ALERT"My blog address: \"http://blog.csdn.net/shallnet\"");  
    return arg + arg;  
}  

第四步,重新編譯內核。依次執行:

make oldconfig  
make bzImage  
make modules  
make modules_install  
make install  

第五步,重新啟動系統然後進入剛新編譯的系統,編寫測試代碼如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

#define __NR_shallnet 337

int main(int argc, const char* argv[])
{
    int     ret;

    ret = syscall(337, 99);

    printf("shallnet() return: %d\n", ret);
    return 0;
}

編譯執行該程序如下:

$ ./target_bin  
shallnet() return: 198  
  
$ demsg  
......  
My blog address: "http://blog.csdn.net/shallnet"  

可以看到我們新加的系統調用執行成功了。

可見建立一個新的系統調用還是很容易的,但是不提倡這麼做,系統調用需要一個系統調用號,需要修改內核代碼,修改之後需要重新編譯內核。linux系統應當儘量避免每出現一個新的抽象就加入一個新的系統調用,通常有其他的方法可以代替系統調用,比如說實現一個設備節點等。

本節源碼下載: http://download.csdn.net/detail/gentleliu/9035717


书籍推荐