新聞中心
1、ELF格式2、可執(zhí)行文件加載3、可執(zhí)行文件執(zhí)行4、總結(jié)在前面的文章中,一、ELF格式在介紹可執(zhí)行文件加載和執(zhí)行之前,內(nèi)核首先會去搜索環(huán)境變量PATH指定路徑下是否有該命令的可執(zhí)行文件。
- 本文目錄導(dǎo)讀:
- 1、ELF格式
- 2、可執(zhí)行文件加載
- 3、可執(zhí)行文件執(zhí)行
- 4、總結(jié)

目前創(chuàng)新互聯(lián)建站已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機、成都網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計、平原網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
在前面的文章中,我們已經(jīng)講解了Linux文件系統(tǒng)的基本概念、目錄結(jié)構(gòu)以及各種類型的文件。今天,我們將深入探討一個非常重要的主題:可執(zhí)行文件的加載和執(zhí)行過程。
作為一名程序員,我們每天都會編寫各種應(yīng)用程序或者腳本,并通過編譯器生成可執(zhí)行文件。但是,在運行這些程序之前,操作系統(tǒng)需要對其進行加載并分配內(nèi)存空間。那么,在Linux中,這個過程具體是如何實現(xiàn)的呢?
一、ELF格式
在介紹可執(zhí)行文件加載和執(zhí)行之前,先來了解一下ELF格式。ELF(Executable and Linkable Format)即“可執(zhí)行與鏈接格式”,它是Unix類操作系統(tǒng)上二進制目標(biāo)代碼所采用的標(biāo)準(zhǔn)格式。
ELF不僅支持靜態(tài)庫和動態(tài)庫等多種形式組合成符號表等信息,并且還可以指定段權(quán)限、節(jié)區(qū)屬性以及調(diào)試信息等內(nèi)容。
當(dāng)然,在使用GCC編譯工具時,默認(rèn)就會生成一個符合ELF規(guī)范的二進制目標(biāo)代碼。
二、可執(zhí)行文件加載
1. 加載方式
當(dāng)用戶從shell命令行輸入某個命令時(例如ls),內(nèi)核首先會去搜索環(huán)境變量PATH指定路徑下是否有該命令的可執(zhí)行文件。
如果找到了,就會將該可執(zhí)行文件加載到內(nèi)存中。這個過程主要包括以下幾個步驟:
(1)檢查權(quán)限:內(nèi)核首先會檢查用戶對該文件是否有讀取和執(zhí)行權(quán)限,只有具備這些權(quán)限才能夠繼續(xù)進行下一步操作。
(2)分配空間:在物理內(nèi)存上為新進程分配一個虛擬地址空間,并根據(jù)程序頭部信息確定各段的大小、屬性以及所需對齊方式等內(nèi)容。同時,在用戶態(tài)和內(nèi)核態(tài)之間建立好映射關(guān)系。
(3)載入代碼段:將可執(zhí)行文件中的代碼段復(fù)制到剛剛分配好的虛擬地址空間中,并設(shè)置相應(yīng)頁表項標(biāo)志位。
(4)載入數(shù)據(jù)段:同樣地,將可執(zhí)行文件中的數(shù)據(jù)段復(fù)制到虛擬地址空間中,并設(shè)置相應(yīng)頁表項標(biāo)志位。
2. 加載器
那么,在Linux系統(tǒng)中,是哪個程序負(fù)責(zé)完成上述工作呢?答案是ld-linux.so.x或者其它類似名稱的動態(tài)鏈接器庫。當(dāng)我們在shell命令行輸入某個命令時,實際上是由此啟動了一個新進程,并且通過動態(tài)鏈接器來完成相關(guān)工作并運行用戶指定程序。
三、可執(zhí)行文件執(zhí)行
1. 入口函數(shù)
當(dāng)我們成功加載完畢某個可執(zhí)行文件后,接下來就是真正的程序運行過程。在C語言中,每個程序都必須包含一個入口函數(shù)main()。
當(dāng)操作系統(tǒng)將控制權(quán)交給該程序時,會首先跳轉(zhuǎn)到該入口地址,并開始執(zhí)行相關(guān)代碼。此時,用戶指定的參數(shù)也會被傳遞進去。
2. 系統(tǒng)調(diào)用
除了main()函數(shù)之外,在Linux內(nèi)核中還提供了許多常用的系統(tǒng)調(diào)用API供我們使用(例如open、read、write等),以便于對各種資源進行讀寫和管理等操作。
這些系統(tǒng)調(diào)用實際上是由用戶態(tài)向內(nèi)核態(tài)發(fā)起請求并獲取返回結(jié)果的過程。而在ELF格式的可執(zhí)行文件中,則需要通過PLT表和GOT表來完成動態(tài)鏈接庫函數(shù)的加載和綁定等工作。
3. 信號處理
在某些特殊情況下(例如按下Ctrl+C組合鍵或者遇到非法指令等錯誤),操作系統(tǒng)可能會向當(dāng)前進程發(fā)送一條信號通知其停止或者重新啟動等操作。
此時,我們需要編寫相應(yīng)信號處理函數(shù),并且注冊到signal() API中以便于捕獲相關(guān)事件并做出相應(yīng)響應(yīng)。
四、總結(jié)
本文主要介紹了Linux源碼解讀系列第七篇:文件系統(tǒng)——可執(zhí)行文件的加載和執(zhí)行過程。通過深入剖析ELF格式及其規(guī)范約束,我們了解了Linux系統(tǒng)如何在內(nèi)存中為可執(zhí)行文件分配虛擬地址空間,并且將其載入到物理內(nèi)存中。
同時,在介紹動態(tài)鏈接庫的加載和使用過程時,我們也深刻認(rèn)識到操作系統(tǒng)與用戶程序之間緊密相連的關(guān)系。最后,希望本文能夠?qū)Υ蠹矣兴鶈l(fā)并提供一些參考價值。
文章標(biāo)題:Linux源碼解讀(七):文件系統(tǒng)——可執(zhí)行文件的加載和執(zhí)行
網(wǎng)頁地址:http://www.5511xx.com/article/coiiseh.html


咨詢
建站咨詢
