Linux內核中添加系統調原理淺析

1. Linux體系結構

  Linux系統的地址空間分爲用戶空間和內核空間,通過系統調用和硬件中斷能夠完成從用戶空間到內核空間的轉移。

技術分享圖片

 

2. 系統調用接口

① 一般情況下,用戶進程不能訪問內核空間。Linux內核中提供了一組用於實現各種系統功能的子程序,用戶可以調用它們訪問Linux內核的數據和函數,這些子程序稱爲系統調用接口(SCI)。

② 系統調用和普通函數的區別:系統調用由操作系統內核實現,運行於內核態;普通函數調用由函數庫或用戶自己提供,運行於用戶態。

 

3. 系統調用分類:主要分3大類

① 進程控制類

  * fork

  * clone

  * execve

  ...

② 文件控制類

  * fcntl

  * open

  * read

  ...

③ 系統控制類

  * ioctl

  * reboot

  ...

 

4.  系統調用工作原理

  系統調用工作原理是(1)進程先用適當的值填充寄存器(R7),(2)然後調用一個特殊的指令(swi),(3)這個指令會讓用戶程序跳轉到一個事先定義好的內核中的一個位置(vector_swi),(4)這位置的代碼會根據寄存器(R7)的值從表sys_call_table中查找相應的函數。

(1)適當的值:系統調用號,定義於文件arch\arm\include\asm\unistd.h中。

#define __NR_restart_syscall        (__NR_SYSCALL_BASE+  0)
#define __NR_exit            (__NR_SYSCALL_BASE+  1)
#define __NR_fork            (__NR_SYSCALL_BASE+  2)
#define __NR_read            (__NR_SYSCALL_BASE+  3)
#define __NR_write            (__NR_SYSCALL_BASE+  4)
#define __NR_open            (__NR_SYSCALL_BASE+  5)
#define __NR_close            (__NR_SYSCALL_BASE+  6)

(2)特殊的指令
  * 在X86 CPU中,這個指令由中斷0x80實現

  * 在ARM中,這個指令是SWI(Software interrupt:軟中斷指令),現在重命名爲SVC

(3)固定的位置:在ARM體系中,這個固定位置爲ENTRY(vector_swi)(arch\arm\kernel\entry-common.S)

(4)相應的函數:內核根據應用程序傳遞來的系統調用號,從系統調用表sys_call_table(sys_call_table中表項定於文件:arch\arm\kernel\calls.S)找到相應的內核函數。

 

5. 向Linux內核中添加新的系統調用

① 在內核代碼的某一位置添加函數,如:向kernel/printk.c中添加

void sys_print()
{
    printk("Hello Kevin, this is a new system call\n");
}

② 把函數添加至sys_call_table,如:向arch\arm\kernel\calls.S中373行添加

CALL(sys_print)

③ 添加系統調用號,如:向arch\arm\include\asm\unistd.h中添加

#define __NR_sys_print        (__NR_SYSCALL_BASE+361)


6. 新的系統調用測試

①應用層測試代碼方法1:

#include <sys/syscall.h>

int main()
{
    syscall(361);
    
    return 0;
}


①應用層測試代碼方法2:

void SystemCallTest()
{
    __asm__ (
        "ldr r7, =361 \n"
        "swi \n"
        :
        :
        :"memory"
    );
}


int main()
{
    SystemCallTest();
    
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章