一、系統呼叫
由於需要限制不同的程式之間的訪問能力, 防止他們獲取別的程式的記憶體資料, 或者獲取外圍裝置的資料, 併發送到網路, cpu劃分出兩個許可權等級 -- 使用者態和核心態。
核心態:cpu可以訪問記憶體的所有資料,包括外圍裝置,例如硬碟,網絡卡,cpu也可以將自己從乙個程式切換到另乙個程式。
使用者態:只能受限的訪問記憶體,且不允許訪問外圍裝置,占用cpu的能力被剝奪,cpu資源可以被其他程式獲取。
如上所述,一方面由於系統提供了保護機制,防止應用程式直接呼叫作業系統的過程,從而避免了系統的不安全性。但另一方面,應用程式又必須取得作業系統所提供的服務,否則,應用程式幾乎無法作任何有價值的事情,甚至無法執行。為此,在作業系統中提供了系統呼叫,使應用程式可以通過系統呼叫的方法,間接呼叫作業系統的相關過程,取得相應的服務。
呼叫流程:
那麼,在應用程式內,呼叫乙個系統呼叫的流程是怎樣的呢?
我們以乙個假設的系統呼叫 xyz 為例,介紹一次系統呼叫的所有環節。
如上圖,系統呼叫執行的流程如下:
1、應用程式 **呼叫系統呼叫( xyz ),該函式是乙個包裝系統呼叫的 庫函式;
2、庫函式 ( xyz )負責準備向核心傳遞的引數,並觸發 軟中斷 以切換到核心;
3、cpu 被 軟中斷 打斷後,執行 中斷處理函式 ,即 系統呼叫處理函式 ( system_call);
4、系統呼叫處理函式 呼叫 系統呼叫服務例程 ( sys_xyz ),真正開始處理該系統呼叫;
執行態切換
linux 通過 軟中斷 實現從 使用者態 到 核心態 的切換。 使用者態 與 核心態 是獨立的執行流,因此在切換時,需要準備 執行棧 並儲存 暫存器 。
核心實現了很多不同的系統呼叫(提供不同功能),而 系統呼叫處理函式 只有乙個。 因此,使用者程序必須傳遞乙個引數用於區分,這便是 系統呼叫號 ( system call number )。 在 linux 中, 系統呼叫號 一般通過 eax 暫存器 來傳遞。
總結起來, 執行態切換 過程如下:
1、應用程式 在 使用者態 準備好呼叫引數,執行 int 指令觸發 軟中斷 ,中斷號為 0x80 ;
2、 cpu 被軟中斷打斷後,執行對應的 中斷處理函式 ,這時便已進入 核心態 ;
3、系統呼叫處理函式 準備 核心執行棧 ,並儲存所有 暫存器 (一般用組合語言實現);
4、系統呼叫處理函式 根據 系統呼叫號 呼叫對應的 c 函式—— 系統呼叫服務例程 ;
5、系統呼叫處理函式 準備 返回值 並從 核心棧 中恢復 暫存器 ;
6、系統呼叫處理函式 執行 ret 指令切換回 使用者態 ;
反彙編menu目錄下的init檔案,共有5處int $0x80的彙編指令,其中一處如圖所示:
驗證了核心中將系統呼叫作為乙個特殊的中斷來處理。
二、系統呼叫過程跟蹤
驗證 x86-64位系統下的系統呼叫初始化過程:start_kernel --> trap_init --> cpu_init --> syscall_init
gdb設定斷點成功,驗證了x86-64位系統下的系統呼叫初始化過程。file vmlinux
target remote:
1234
b start_kernel
b trap_init
b cpu_init
b syscall_init
三、socket呼叫初步分析
使用gdb跟蹤replyhi的執行過程。
在menu目錄下執行 make rootfs 啟動 memuos。
在linux-5.0.1目錄下開啟新的終端,執行命令,如下:
gdb執行結果如下:file vmlinux
target remote:
1234
b __sys_socket
b __sys_bind
b __sys_listen
b __sys_shutdown
可見在replyhi 執行過程中,呼叫了socket()、bind()、listen()等api 。
Socket 與系統呼叫深度分析
本次實驗主要從以下幾個方面對socket和系統呼叫之間的關係 socket api 和 系統呼叫關係 系統呼叫機制 socket相關系統呼叫核心函式和跟蹤驗證 系統呼叫一般發生在中斷的時候。當中斷發生時,系統就會進入核心態指向相關的系統呼叫。相信考過408的同學對下圖應該是很熟悉的。這個圖大概的描述...
SOCKET使用者介面與系統呼叫關係
所有的socket系統呼叫的總入口是sys socketcall 在include linux syscalls.h中定義 其中,param call 標識介面編號,param args 是介面引數指標 介面編號的定義在 include uapi linux net.h中定義 介面編號對應的引數個數...
SOCKET使用者介面與系統呼叫關係(2)
上一節中講述了socket呼叫的總入口sys socketcall的巨集定義形式,該定義形式還廣泛用於其他介面api。現在我們來看看sys socketcall的實現方式。在net socket.c 中,sys socketcall的實現如下 2465 2466 api序號鑑定,需要在socket ...