在上一章我們學習了程序的建立過程,但是新程序在被建立之後還如果要執行新的**,這個時候就輪到execve()
系統呼叫出場了,他的主要作用就是將目標**讀入程序記憶體空間中的**段。
execve()
函式的入口是sys_execve()
系統呼叫,原型如下:(路徑:/kernel-4.19/include/linux/syscalls.h)
asmlinkage long sys_execve(const char __user *filename, //需要執行的檔案的絕對路徑
const char __user *const __user *ar**, //傳入系統呼叫的引數
const char __user *const __user *envp); //環境變數
第乙個引數是要被執行的程式的路徑,第二個引數則向程式傳遞了命令列引數,第三個引數則向程式傳遞環境變數[1]。
當進入sys_execve()
系統呼叫時,在中斷處理程式中呼叫了do_execve()
[2]:(路徑:/kernel-4.19/fs/exec.c)
syscall_define3(execve,
const char __user *, filename,
const char __user *const __user *, ar**,
const char __user *const __user *, envp)
在進入do_execve()
之後,完成了一系列引數賦值,接著又呼叫了do_execveat_common()
:(路徑:/kernel-4.19/fs/exec.c)
int do_execve(struct filename *filename,
const char __user *const __user *__ar**,
const char __user *const __user *__envp)
; struct user_arg_ptr envp = ;
return do_execveat_common(at_fdcwd, filename, ar**, envp, 0);
}
在do_execveat_common
裡面又是直接呼叫的__do_execve_file
,主要動作如下[4]:
呼叫unshare_files()
為程序複製乙份檔案表;
呼叫kzalloc()
建立乙個linux_binprm
結構體例項bprm
(此結構體用於管理一些與載入的二進位制檔案相關的引數);
呼叫do_open_execat
查詢並開啟二進位制檔案;
呼叫sched_exec()
找到最小負載的cpu,用來執行該二進位制檔案;
根據獲取的資訊,填充bprm
中的file
、filename
、interp
成員;
呼叫bprm_mm_init()
建立程序的記憶體位址空間,為新程式初始化記憶體管理.並呼叫init_new_context()
檢查當前程序是否使用自定義的區域性描述符表;如果是,那麼分配和準備乙個新的ldt;
填充bprm
中的argc
、envc
成員;
呼叫prepare_binprm()
檢查該二進位制檔案的可執行許可權;最後,kernel_read()
讀取二進位制檔案的頭128位元組(這些位元組用於識別二進位制檔案的格式及其他資訊,後續會使用到);
呼叫copy_strings_kernel()
從核心空間獲取二進位制檔案的路徑名稱;
呼叫copy_string()
從使用者空間拷貝環境變數和命令列引數;
至此,二進位制檔案已經被開啟,bprm
中也記錄了重要資訊, 核心開始呼叫exec_binprm()
執行可執行程式;
釋放linux_binprm
資料結構,返回從該檔案可執行格式的load_binary
中獲得的**。
__do_execve_file()
函式**長度較長,故不在此貼出,用下圖來配合說明其大體的流程[3]:
說明.png)
在這裡面涉及到乙個重要的結構體linux_binprm
,用來儲存要執行的檔案相關的資訊,部分**如下:(路徑:/kernel-4.19/include/linux/binfmts.h)
struct linux_binprm
本章我們學習了excve()
的呼叫過程:sys_execve()
->do_execve()
->do_execveat_common()
->__do_execve_file()
,在最後乙個函式中完成了大部分功能,在此之後程序就可以執行新的程式了。程序執行完畢之後將會結束其生命週期,這部分將在下一章講解。
參考:
[1]Leetcode第五十題 Pow x, n
題目 實現 pow x,n 即計算 x 的 n 次冪函式。示例 1 輸入 2.00000,10 輸出 1024.00000 示例 2 輸入 2.10000,3 輸出 9.26100 示例 3 輸入 2.00000,2 輸出 0.25000 解釋 2 2 1 22 1 4 0.25 說明 100.0 ...
《道德經》第五十章
出生入死。生之徒,十有三 死之徒,十有三 人之生,動之於 死地,亦十有三。夫何故?以其生之厚。蓋聞善攝生者,路行不遇兕虎,入軍不被 甲兵 兕無所投其角,虎無所用其爪,兵無所容其刃。夫何故?以其 無死地。易解 出離維生之道就入於速死之途。人世間,屬於長壽的,佔十分之三 屬於短命的,佔十分之三 因為行舉...
程式設計訓練第五十期 合併區間
以陣列 intervals 表示若干個區間的集合,其中單個區間為 intervals i starti,endi 請你合併所有重疊的區間,並返回乙個不重疊的區間陣列,該陣列需恰好覆蓋輸入中的所有區間。1.排序 雙指標 如果我們按照區間的左端點排序,那麼在排完序的列表中,可以合併的區間一定是連續的。我...