本文我將基于 ARM 體系結構角度,從 Linux 應用層例子到內核系統調用函數的整個過程來梳理一遍,講清楚linux系統調用實現原理,這里我們以open系統調用為例來講解。
在應用層調用 open 系統調用時,實際上調用的是 C 標準庫函數,具體的代碼如下:
其中,open 函數的第一個參數是要打開的文件路徑,第二個參數則是打開方式(例如只讀、讀寫等)。在這里我們使用了 O_RDONLY 參數表示只讀。
在 C 標準庫中,open 函數實際上是通過系統調用來完成文件的打開操作。接下來,我們來看一下系統調用的具體實現。
在 ARM 架構的 Linux 內核中,系統調用的處理流程分為以下幾步:
1.應用程序通過 swi 匯編指令觸發中斷,將 CPU 切換到特權模式。
在 ARM 架構中,每一個系統調用都對應有一個系統調用號,比如open系統調用的號碼就是5,應用程序通過 swi 指令從用戶態切換到內核態,CPU進入特權模式,通過R7寄存器將中系統調用號傳遞給內核。下面是 open 系統調用的匯編代碼示例:
2.中斷處理程序根據傳遞的系統調用號找到對應的系統調用函數。
內核中的系統調用處理程序是通過一張系統調用表來實現的,該表包含了所有系統調用的函數指針。當中斷處理程序接收到一個系統調用請求時,它會根據系統調用號查找該表,并跳轉到相應的系統調用函數。在 ARM 架構中,系統調用表存儲在地址為 0x9000 的內存位置上。
對于 open 系統調用,在內核中的實現代碼為 sys_open() 函數,其定義在 fs/open.c 文件中。在 ARM 架構中,sys_open() 函數的函數指針存儲在系統調用表的第 5 個位置上。
3.將用戶空間的參數復制到內核空間,并在系統調用函數中進行相應的操作。
在 ARM 架構中,內核將用戶空間和內核空間分開,以確保用戶空間的數據不會被惡意程序修改。因此,在執行系統調用之前,內核需要將用戶空間的數據復制到內核空間。對于 open 系統調用,它的參數包括文件名和標志,這些參數都需要從用戶空間復制到內核空間。
在內核中,copy_from_user() 和 copy_to_user() 函數用于從用戶空間復制數據到內核空間和從內核空間復制數據到用戶空間。對于 open 系統調用,它需要從用戶空間復制文件名和標志,并將它們傳遞給 sys_open() 函數進行處理。下面是 sys_open() 函數的代碼示例:
4.將處理結果返回給用戶空間,并將 CPU 切換回用戶模式。
在 ARM 架構中,系統調用的返回值通過 r0 寄存器傳遞給應用程序。對于 open 系統調用,它的返回值為文件描述符,即打開文件的句柄。如果打開文件成功,則返回一個非負整數,表示新的文件描述符;否則,返回一個負數,表示錯誤代碼。
在 sys_open() 函數中,如果成功打開文件,則將文件描述符安裝到當前進程的文件描述符表中,并返回該文件描述符。否則,返回錯誤代碼。下面是 open 系統調用的匯編代碼示例:
最后,當處理完 open 系統調用后,中斷處理程序將 CPU 切換回用戶模式,將處理結果返回給應用程序。
-
寄存器
+關注
關注
31文章
5325瀏覽量
120052 -
Linux系統
+關注
關注
4文章
592瀏覽量
27357 -
ARM處理器
+關注
關注
6文章
360瀏覽量
41668 -
觸發中斷
+關注
關注
0文章
11瀏覽量
6560 -
函數指針
+關注
關注
2文章
56瀏覽量
3775
發布評論請先 登錄
相關推薦
評論