系統呼叫過程詳解

2021-07-25 03:53:14 字數 1812 閱讀 2343

整個過程如下:首先指令流執行到系統呼叫函式時,系統呼叫函式通過int 0x80指令進入系統呼叫入口程式,並且把系統呼叫號放入%eax中,如果需要傳遞引數,則把引數放入%ebx,%ecx和%edx中。進入系統呼叫入口程式(system_call)後,它首先把相關的暫存器壓入核心堆疊(以備將來恢復),這個過程稱為保護現場。保護現場的工作完成後,開始檢查系統呼叫號是不是乙個有效值,如果不是則退出。接下來根據系統呼叫號開始呼叫系統呼叫處理程式(這是乙個正式執行系統呼叫功能的函式),從系統呼叫處理程式返回後,就會去檢查當前程序是否處於就緒態、程序時間片是否用完,如果不在就緒態或者時間片已用完,那麼就會去呼叫程序排程程式schedule(),轉去執行其他程序。如果不執行程序排程程式,那麼接下來就會開始執行ret_from_sys_call,顧名思義,這這個程式主要執行一些系統呼叫的後處理工作。比如它會去檢查當前程序是否有需要處理的訊號,如果有則去呼叫do_signal(),然後進行一些恢復現場的工作,返回到原先的程序指令流中。至此整個系統呼叫的過程就結束了。

注:關於程序排程函式schedule()和訊號處理函式do_signal()我們會在後面的部落格中具體進行講解。

好了,知道了系統呼叫的大致執行過程,下面我們來看看linux0.11核心是如何實現這一功能的。

我們以linux0.11核心中init/main.c中的fork()函式為例(fork()是乙個系統呼叫)。

在main.c中有這麼幾行**:

這裡的_syscall0表示內嵌巨集**,(不明白?沒關係),我們只要知道執行fork(),就相當於執行_syscall0(),它的定義在include/unistd.h中:

這是一段嵌入在c語言的彙編**(注:在linux核心中有很多這樣的**,為的是在某些關鍵的地方使用彙編**提供執行效率)。這段**的大致含義是:執行int 0x80,把系統呼叫號放入%eax。這個時候系統就自動進入了系統呼叫入口程式_system_call中,它在kernel/system_call.s中:

第81-82行的**是判斷系統呼叫號是不是有效值。從第83-93就在進行一些入棧的操作,緊接著第94行**執行call _sys_call_table(,%eax,4),這個_sys_call_table是什麼東西呢?它就是系統呼叫處理函式的指標陣列,它裡面包括了所有的系統呼叫。這個指標陣列定義在include/linux/sys.h,截個圖給大家看看

看到沒?我們要呼叫的fork()它的處理函式就是sys_fork(),它處在第3個位置上,所以當我們執行call _sys_call_table(,%eax,4)時,它就自動去執行sys_fork()啦!從系統呼叫處理函式返回後,第96-100的**會去判斷需不需要執行排程函式schedule。如果不需要的話,就開始執行ret_from_sys_call了,它同樣在kernel/system_call.s中:

這個函式會去檢查是否有訊號需要處理,如果有則呼叫do_signal函式。標號3那個位置的彙編**就是進行一些恢復現場的工作。

linux0.11核心的系統呼叫的整個過程大概就是這樣!

fork系統呼叫過程

又是查詢資料,又是看原始碼,折騰了大半天,終於把fork的過程弄完了,但是後面的跟蹤狀態還不太懂,等具體後面弄清楚了,再加上。核心是2.6.11版本的。fork 系統呼叫 我們執行乙個系統呼叫時,系統將呼叫巨集指令 syscall0 define syscall0 type,name type na...

Linux系統呼叫過程

linux系統分為核心空間和使用者空間 應用程式通過引發乙個異常來促使系統切換到核心狀態 去執行系統呼叫的處理函式 對於ia 32體系 通過int 0x80指令觸發該中斷 具體可參考gun庫 sysdeps unix sysv linux arch syscall.s 當系統呼叫 open read...

例項分析系統呼叫過程

我們由剛開始接觸程式設計的乙個程式說起。上述一段 通過gcc編譯,生成乙個.o檔案,執行,就能輸出printf函式要輸出的文字。那麼,對於printf 函式這個呼叫,作業系統到底發生了什麼?為了方便管理,我們將計算機系統資源分為使用者態和核心態,對於核心部分,一般是對程序資源進行管理,而這些東西是不...