7Linux內核如何裝載和啟動一個可執行程序

安大大 + 原創作品轉載請注明出處 + 《Linux操作系統分析》MOOC課程


知識要點

1 可執行程序是怎么得來的

對于c代碼來說,先是經過編譯器的預處理,然后編譯成匯編代碼。再由匯編器把匯編代碼編譯成目標代碼,然后再連接成可執行文件。可執行文件由操作系統加載到內存里執行。

shiyanlou:~/ $ cd Code                                                
shiyanlou:Code/ $ vi hello.c                                          
shiyanlou:Code/ $ gcc -E -o hello.cpp hello.c -m32  #對c程序預處理,hello.cpp是預處理的中間文件                  
shiyanlou:Code/ $ vi hello.cpp                                        
shiyanlou:Code/ $ gcc -x cpp-output -S -o hello.s hello.cpp -m32 #編譯成匯編代碼     
shiyanlou:Code/ $ vi hello.s                                          
shiyanlou:Code/ $ gcc -x assembler -c hello.s -o hello.o -m32 #編譯成目標代碼        
shiyanlou:Code/ $ vi hello.o #二進制文件,當中已經有一些機器指令                                         
shiyanlou:Code/ $ gcc -o hello hello.o -m32  #連接成可執行程序                          
shiyanlou:Code/ $ vi hello  #hello.o和hello 都是ELF格式的文件                                          
shiyanlou:Code/ $ gcc -o hello.static hello.o -m32 -static  #把所有依賴的內容都放在了程序的內部 
shiyanlou:Code/ $ ls -l                                               
-rwxrwxr-x 1 shiyanlou shiyanlou   7292  3\u6708 23 09:39 hello
-rw-rw-r-- 1 shiyanlou shiyanlou     64  3\u6708 23 09:30 hello.c
-rw-rw-r-- 1 shiyanlou shiyanlou  17302  3\u6708 23 09:35 hello.cpp
-rw-rw-r-- 1 shiyanlou shiyanlou   1020  3\u6708 23 09:38 hello.o
-rw-rw-r-- 1 shiyanlou shiyanlou    470  3\u6708 23 09:35 hello.s
-rwxrwxr-x 1 shiyanlou shiyanlou 733254  3\u6708 23 09:41 hello.static #比hello大很多
2 目標文件的格式,

.o文件和可執行文件都是目標文件。



ELF(Executable and Linkable Format)可執行與可鏈接格式,是一個文件格式的標準。在目標文件里邊已經是二進制兼容的格式,即這個目標文件已經適應到某種CPU體系結構上的二進制指令(ABI)。

3 在ELF當中有三種主要的目標文件
  • 一個可重定位(relocatable)文件(主要是.o文件)保存著代碼和適當的數據,用來和其他的object文件一起來創建一個可執行文件或者是一個共享文件。
  • 一個可執行(executable)文件保存著一個用來執行的程序;該文件指出了 exec(BA_OS)如何來創建程序進程映像。
  • 一個共享object文件(主要是.so文件)保存著代碼和合適的數據,用來被下面的兩個連接器鏈接。第一個是連接編輯器(靜態鏈接)[參看ld(SD_CMD)],可以和其他的重定位和共享object文件來創建其他的object。第二個是動態鏈接器,聯合一個可執行文件和其他的共享object文件來創建一個進程映象。
4 目標文件的格式ELF

Object文件參與程序的聯接(創建一個程序)和程序的執行(運行一個程序)。
object 文件格式提供了一個方便有效的方法并行的視角看待文件的內容,
在他們的活動中,反映出不同的需要。

 Linking 視角                       Execution 視角
  ============                      ==============
  ELF header                        ELF header
  Program header table (optional)   Program header table
  Section 1                         Segment 1
  ...                               Segment 2
  Section n                         ...
  Section header table              Section header table (optional)

一個ELF頭在文件的開始,保存了路線圖(road map),描述了該文件的組織情況。程序頭表(program header table)告訴系統如何來創建一個進程的內存映象。section頭表(section header table)包含了描述文件sections的信息。每個section在這個表中有一個入口;每個入口給出了該section的名字,大小,等等信息。

Entry point address是程序的起點
可執行文件的格式和進程的地址空間有一個映射關系,
可執行程序加載的主要工作。

當創建或增加一個進程映像的時候,系統在理論上將拷貝一個文件的段到一個虛擬的內存段


+ Figure 2-5: Executable File

           File Offset   File                  Virtual Address
           ===========   ====                  ===============
                     0   ELF header
  Program header table
                         Other information
                 0x100   Text segment          0x8048100
                         ...
                         0x2be00 bytes         0x8073eff
               0x2bf00   Data segment          0x8074f00
                         ...
                         0x4e00 bytes          0x8079cff
               0x30d00   Other information
                         ...

參考:ELF文件格式(中文) 英文

5 靜態鏈接的ELF可執行文件與進程的地址空間

Entry point address 是可執行文件加載到內存中開始執行的第一行代碼
一般靜態鏈接會將所有代碼放在一個代碼段
動態鏈接的進程會有多個代碼段

6裝載可執行程序之前的工作

命令行參數和環境變量是如何保存和傳遞的
調用execve系統調用時,要加載的可執行程序,把原來的進程環境覆蓋掉,覆蓋掉之后,用戶態堆棧被清空。
命令行參數和環境變量是如何進入新進程的堆棧的
創建一個新的用戶態堆棧時,把命令行參數的內容和環境變量的內容,通過指針的方式傳遞到系統調用的內核處理函數。內核處理函數在創建一個新的可執行程序的用戶態堆棧時,會把argv和envp拷貝到用戶態堆棧里,來初始化新的可執行程序執行的上下文環境。
先函數調用參數傳遞,再系統調用參數傳遞。

7

動態鏈接分為可執行程序裝載時動態鏈接和運行時動態鏈接
linux下動態鏈接文件.so,windows是dll


裝載可執行程序之前的工作

總結
把ELF可執行文件加載到內存中,通過ELF頭部的信息,找到程序的入口執行。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容