2015-10-06 50 views

回答

3

有關於這上LWN一個詳細的文章:https://lwn.net/Articles/631631/

具體地,代碼由load_elf_binary()加載:http://lxr.free-electrons.com/source/fs/binfmt_elf.c?v=3.18#L571

即功能從do_execve_common()這當然是從execve()稱爲所謂的(間接)和朋友:http://lxr.free-electrons.com/source/fs/exec.c?v=3.18#L1513

正如您可能已經知道的,execve()和朋友通常在創建新過程後(通過fork())調用。所以在「創建流程」和「加載ELF」之間幾乎沒有什麼關係。

最後,通過由MMU的硬件異常調用的頁錯誤處理程序將代碼從虛擬物理存儲器加載到物理存儲器。

+0

那麼你和我涵蓋了兩個不同的方面。尼斯。 – Joshua

+1

謝謝你的鏈接。但是二進制文件的實際代碼段在第一次開始正確執行之前是不會被加載的?當進程第一次嘗試執行時,它會在第一條指令的地址上發生頁面錯誤。不是當實際的文件被加載到內存中嗎? (假設這個程序是第一次運行) – woodstok

+1

@MIhahail:當你問「是不是當實際的文件被加載到內存中?」我想你的意思是物理記憶?在這種情況下,我認爲你是對的,直到最後一刻才能加載到物理RAM中。 –

2

內核會將ELF exe映像加載到映像標頭所示的位置。 (我們記得Unix完全依賴虛擬內存來正常工作,請參閱fork()。)內核具有加載共享庫的例程;但是除了裝載機本身,這些很少使用。內核然後跳轉到圖像中指定的起始地址。如果有一個加載器,這個跳轉就會被劫持進入加載器。

大多數共享庫都由加載器加載(/lib/ld-linux-so.2 for i386),這是一個共享庫。加載器可以執行諸如定位共享庫在系統中的位置等內容,而不是依賴嵌入在exe鏡像中的絕對路徑,就像內核所做的那樣。加載器將庫映射到內存並執行修復。加載器保持加載到內存中,並可用於按需加載其他庫(請參閱dlopen())。