Unix高級編程學習筆記--系統調用簡介

《Unix高級編程學習筆記》 1git

系統調用簡介

  1. 爲用戶空間提供了一種硬件的抽象接口
  2. 保證了系統的穩定和安全
  3. Linux中進程都運行在虛擬系統中

POSIX、API、C庫

POSIX、API、C庫和syscall之間的關係 github

關係圖

系統調用

  • 系統調用一般但不絕對,以long類型的返回值(爲與64位的硬件體系結構保持兼容)
  • 表示對錯:負數表示錯誤,0值表示成功,出錯將錯誤碼寫入errno全局變量,經過perror()庫函數翻譯成用戶理解的錯誤字符串。
  • 宏定義: SYSCALL_DEFINE0(###)
  • 含義: 定義一個在內核中無參數的系統調用 用例:
//定義內核中的系統調用getpid()的實現
//展開前
SYSCALL_DEFINE0(getpid)
{
    return task_tgidvnr(current); //return current->tgid
}

//展開後
asmlinkage long sys_getpid(void){
    return task_tgidvnr(current); //return current->tgid
}
複製代碼

用例:編程

//定義內核中的系統調用bar()的實現
//展開前
SYSCALL_DEFINE0(bar)
//展開後
asmlinkage long sys_bar()
複製代碼

注:用戶空間返回int,內核空間返回long安全

系統調用號

用於關聯繫統調用。用戶進程空間的進程執行一個系統調用時,使用系統調用號指明到底執行哪一個系統調用,且不會說起系統調用的名稱。bash

特色:

  1. 一旦分配便不會再有任何改變;
  2. 系統調用號一旦刪除系統調用號也不會被回收;
  3. sys_ni_syscall()返回-ENOSYS,專門填補無效系統調用;
  4. sys_call_table 記錄全部已註冊過的系統調用,在x86-64中,定義於arch/i386/kernel/syscall_64.c中,併爲每一個系統調用指定惟一的系統調用號

系統調用號的性能

很高:上下文切換時間短,進出內核被優化得簡潔高效,系統調用處理程序和系統調用簡潔函數

系統調用處理程序

告訴內核須要切換到內核態,讓內核表明應用程序在內核空間執行系統調用 實現機制: 系統調用處理程序:引起一個異常促使系統謝歡到內核態去執行異常處理程序,叫syscall_call()性能

指定恰當的系統調用

  1. x86上將系統調用號經過eax傳遞給內核
  2. 再執行system_call()
  3. 系統調用號與NR_syscalls相比較,大於等於NR_syscalls則返回-ENOSYS,不然執行相應的系統調用
call *sys_call_table(,%eax, 8)
//8表明系統調用表中表項以64位類型存放,則結果等於 系統調用號×4 用於查詢系統調用位置。
//x86-32則用4代替8
複製代碼

調用系統系統調用處理程序以執行一個系統調用

參數傳遞

  1. x86-32系統中前五個參數放置在ebx, ecx, edx, esi和edi
  2. 六個及六個以上則用單獨的寄存器存放指向全部這些參數在用戶空間的指針

系統調用的實現

實現系統調用

  1. 明確此係統函數應該作什麼
  2. 不提倡採用多用途的系統調用,考慮參數、返回值、錯誤碼
  3. 接口應儘可能爲將來多作考慮,並考慮可移植性

參數驗證

  1. 檢查他們的參數是否合法有效
  2. 檢查用戶提供的指針是否有效

系統調用上下文

綁定一個系統調用的最後步驟

編寫完一個系統調用後,將其註冊誠正式的系統調用學習

  1. 在系統調用表的最後加入一個表項其中系統調用號即爲該系統調用在全部系統調用中的次序
  2. 對全部支持的各類體系結構,系統調用號必須定義於<asm/unistd.h>
  3. 系統調用必須被編譯進系統內核,即放進kernel/下的一個相關文件

從用戶空間訪問系統調用

一般,系統調用靠C庫支持,若是僅僅寫出系統調用,glibc庫並不支持,怎麼辦呢 答:宏_syscalln(),其中n範圍爲0~6表明傳遞給系統調用的參數個數,功能爲設置好寄存器並調用陷入指令 例子:優化

//open()系統調用定義
long open(const char* filename, int flags, int mode)
複製代碼

不靠庫支持,直接調用此係統調用的宏形式ui

#define NR_open 5
_syscall3(long, open, const char*, filename, int, flags, int, mode)
複製代碼

在Android系統中系統調用的應用

在Android系統中,_syscall()syscall()替代,且每一種Android支持的系統調用的參數形式都在Android源碼中被SYSCALLS.txt記錄,咱們能夠根據系統調用的知識,並結合SYSCALLS.txt,能夠很輕易地寫出本身對應的的syscall()。

相關文章
相關標籤/搜索