Linux系統呼叫及示例

2021-07-30 13:48:22 字數 4001 閱讀 9642

學習linux系統呼叫時先明確乙個概念:一般情況下,應用程式通過應用程式設計介面api而不是直接通過系統呼叫來程式設計

應用程式設計介面api與系統呼叫的關係如下:(應用程式程式設計介面實際上並不需要和核心提供的系統呼叫對應)

(1)乙個api可以實現成乙個系統呼叫

(2)乙個api可以通過呼叫多個系統呼叫來實現

(3)乙個api可以完全不使用任何系統呼叫

來說說系統呼叫的一些共性吧:

1.系統呼叫(在linux中常稱作syscalls)通常通過函式進行呼叫

2.它們通常都需要定義乙個或幾個引數

3.系統呼叫通常會通過乙個long型別的返回值來表示成功或者錯誤

注意:用乙個負的返回值來表明錯誤;用乙個0值通常(不絕對)表明成功

系統呼叫號很重要:

每個系統呼叫被賦予乙個系統呼叫號,系統呼叫號關聯系統呼叫,當使用者空間的程序執行乙個系統呼叫的時候,這個系統呼叫號就被用來指明到底是要執行哪個系統呼叫,程序不會提及系統呼叫的名稱。注意:系統呼叫號相當關鍵,一旦分配就不能再有任何變更,否則編譯好的應用程式就會崩潰。此外,如果乙個系統呼叫被刪除,它所占用的系統呼叫號也不允許被**利用,否則,以前編譯過的**會呼叫這個系統呼叫,造成混亂。(linux有乙個「未實現」系統呼叫sys_ni_syscall(),它除了返回-enosys外不做任何其他工作,如果乙個系統呼叫被刪除,或者變得不可用,這個函式就要負責「填補空位」)

系統呼叫表(sys_call_table):

表中存放每個的系統呼叫的入口位址(函式指標);

每乙個體繫結構都有對應的乙個系統呼叫表;

如x86平台的系統呼叫表arch/x86/kernel/syscall_table_32.s

如arm平台的系統呼叫表arch/arm/kernel/entry-common.s

entry(sys_call_table)

#include"calls.s"//arch/arm/kernel/calls.s檔案內容如下:

/*0 */ 

call(sys_restart_syscall)

call(sys_exit)

call(sys_read)

call(sys_write)

/*5 */ 

call(sys_open)

call(sys_close)

..........

系統呼叫處理過程:

對於arm來說,系統軟中斷的入口處理程式是vector_swi(arch/arm/kernel/entry-common.s)

entry(vector_swi)

@獲取系統呼叫號到scno(r7)中;

@載入sys_call_table表到tbl變數中

@呼叫系統呼叫

基於tiny4412開發板的系統呼叫流程及示例:

linux核心的唯一訪問介面是系統呼叫,不同平台下的系統呼叫數目不一樣,在arm中,通用的系統呼叫有390個。通過修改核心的原始碼,增加第391個系統呼叫到核心中。

第一步:往核心新增乙個自定義系統呼叫

在核心原始碼的arch/arm/kernel/sys_arm.c 檔案中新增乙個系統呼叫的實現:

gedit arch/arm/kernel/sys_arm.c

在檔案最後新增如下**,這個就是系統呼叫的實現**:

asmlinkage long sys_foo(void)

第二步:將系統呼叫新增到系統呼叫表中

gedit arch/arm/kernel/calls.s

在系統呼叫號為390後面新增,如下藍色部分

/* 385 */  call(sys_memfd_create)

call(sys_bpf)

call(sys_execveat)

call(sys_use***ultfd)

call(sys_membarrier)

call(sys_mlock2)

call(sys_foo)

第三步:新增系統呼叫號

gedit arch/arm/include/uapi/asm/unistd.h

在系統呼叫號為390後面新增,如下藍色部分

#define __nr_bpf                (__nr_syscall_base+386)

#define __nr_execveat                (__nr_syscall_base+387)

#define __nr_use***ultfd             (__nr_syscall_base+388)

#define __nr_membarrier                  (__nr_syscall_base+389)

#define __nr_mlock2                 (__nr_syscall_base+390)

#define __nr_foo               (__nr_syscall_base+391)

第四步:修改系統呼叫數目

gedit arch/arm/include/asm/unistd.h

#include

*this may need to be greater than __nr_last_syscall+1 in order to

*account for the padding in the syscall table

#define __nr_syscalls(392)//

該值要大於等於

」最大的系統呼叫號+1」

並且為4

的整數倍,對齊

第五步: 新增系統呼叫函式的宣告到頭檔案中

gedit include/linux/syscalls.h

在檔案的最後新增如下藍色部分;

asmlinkage long sys_open_by_handle_at(int mountdirfd,

struct file_handle __user *handle,

int flags);

asmlinkage long sys_setns(int fd, int nstype);

asmlinkage long sys_foo(void);

#endif

第六步:新增完畢後,重新編譯核心,並且使用重新編譯的核心來啟動開發板

make  uimage  loadaddr=0x40008000  -j2

以上就是新增乙個系統呼叫的過程,可通過一下應用程式做測試:

#include

#include

#include

int main(void)

long stack_size;

stack_size= syscall(391);//系統一般會通過c庫來呼叫系統呼叫,但是自己定義的系統呼叫缺少c庫的支援,只能使用巨集來呼叫系統呼叫

printf("thekernel stack size is %ld\n",stack_size);

return0;

交叉編譯上面的測試程式,在開發板上執行檢視效果

四 系統呼叫示例

獲取輸出檔名 開啟輸入檔案 如果檔案不存在,出錯退出 建立輸出檔案 如果檔案存在,出錯退出 迴圈直到讀取結束 關閉輸出檔案 在螢幕顯示完成完成資訊 正常退出 這裡涉及到的系統呼叫是 define sys write 5 define sys read 6 define sys close 7 def...

Linux 系統呼叫及核心除錯

編號後三位 411,參考孟寧老師 wget tar xzvf linux 5.0.3.tar.gz sudo apt install flex bison libssl devmake i386 defconfig make make j8 include intmain gcc o init in...

Linux系統呼叫及效能提公升

如何高效執行linux系統呼叫 linux的執行環境 核心空間 使用者空間 可以形象的把我們的整個linux執行環境想象成現實中的銀行,銀行的工作人員是核心空間,而使用者空間就是我們小老百姓,中間的視窗是為了實現我們和銀行工作人員進行交流進行業務辦理,那麼為什麼我們要有個隔板呢?那也是為了讓銀行的內...