linux系統調用過程理解

用戶可以通過兩種方式使用系統調用:

第一種方式是通過C庫函數,包括系統調用在C庫中的封裝函數和其他普通函數。(如write,read,kill,mkdir等函數)

第二種方式是使用_syscall宏。2.6.18版本之前的內核,在include/asm-i386/unistd.h文件中定義有7個_syscall宏,分別是:

_syscall0(type,name)  
_syscall1(type,name,type1,arg1)  
_syscall2(type,name,type1,arg1,type2,arg2)  
_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)  
_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  
_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)  
_syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6)

這裏介紹第二種方式(其實第一種方式本質上就是第二種方式,只不過C庫函數對其進行了封裝)

先舉個例子

如下圖,testsyscall調用後,根據宏定義_syscall0會將返回值int和函數名傳入。後面會講到syscall

以下就是如何產生int80中斷

根據彙編中傳入的宏定義找到對應的系統調用號,這個時候已經由彙編產生int80軟中斷,切換到內核態了。然後再通過調用號在system_call_table中根據偏移量找到對應的內核態中該系統調用函數,如open就找到了sys_open

 

 

參數傳遞:

函數需要傳入幾個參數,就調用對應個數的syscalln(),其中n的範圍從0到6。代表需要傳遞給系統調用的參數個數,這是由於該宏必須瞭解到底有多少參數按照什麼次序壓入寄存器

 

對於每個宏來說,都有2+ n個參數。

第一個參數對應着系統調用的返回值類型。

第二個參數是系統調用的名稱。再以後是按照系統調用參數的順序排列的每個參數的類型和名稱。

 

(我的理解:第0個,第1個參數是固定的,後面2-6的值就是參數。)

 

 

如上圖所示,type是返回類型,name就是系統調用名稱。(就是說open函數調用後在彙編裏會組合爲_NR_open)

 


發佈了28 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章