可執行文件可以是具有不同格式的二進制文件,也可以是一個文本的腳本。可執行文件映像中包含了進程執行的代碼和數據,同時也包含了操作系統用來將映像正確裝入內存并執行的信息。
在Linux中,當前的“本地”(系統默認的)可執行文件格式是ELF[15] (Executable and Linking Format)可執行鏈接格式。由于先前的a.out格式難于實現共享庫,不能適用于動態鏈接,所以目前已經全部被ELF所替換。不過,Linux仍然為 a.out保留了一個二進制處理程序,但通常是使用ELF。
Linux的加載程序一般是根據內嵌在可執行文件開頭的“magic序列”(一個特殊字節序列)來識別文件,有時也會通過文件名的一些特性。例如,Java編譯處理程序可以保證其文件名以.class結尾,并且文件起始前四個字節是 0xcafebabe,這是Java標準所定義的。下面是2.4版本內核在Intel體系下所提供的二進制處理程序,理論上,Linux靈活到足以處理幾乎所有的目標文件格式。
(1)a.out(在fs/binfmt_aout.c中):這是為了支持原來風格的Linux二進制文件。它的存在主要是為了滿足一些系統的向后兼容的需要,但是基本上a.out已經光榮退役了。
(2)ELF(在fs/binfmt_elf.c中):目前是Linux默認的二進制文件格式。該格式在可執行文件和共享庫中都廣泛使用。最新的Linux系統 (例如Red Hat 9)一般只預裝了ELF二進制文件解釋器,但是特殊情況下要決定加載a.out二進制文件,那么系統也通過模塊的方式,對它提供支持。雖然ELF被作為慣用的Linux本地格式,但也和其它格式一樣使用同一個加載處理程序。
(3)EM86(在fs/binfmt_em86.c中):允許在Alpha機器上運行Intel的Linux二進制文件,仿佛它們就是Alpha的本地二進制文件。
(4)Java(在fs/binfmt_java.c中):可以不必每次都定義Java字節碼的解釋程序就可以執行Java的.class文件。這種機制和腳本中使用的機制類似,通過把.class文件的文件名作為參數傳遞,處理程序返回執行整型字節碼的解釋程序。從用戶的觀點來看,Java二進制文件是作為本地可執行文件處理的。
(5)misc(在fs/binfmt_misc.c中):這是最明智地使用二進制處理程序的方法,這個處理程序通過內嵌的特征數字或者文件名后綴可以識別出各種二進制格式,不過最優秀的特性是它可以在運行期配置,而不是只能在編譯期配置。因此,只要遵循其規則,就可以快速的增加對新二進制文件的支持,而不用重新編譯內核,也無須重新啟動機器。Linux源程序文件中的注釋建議最終使用它來取代Java和EM86二進制處理程序。
(6)腳本(在fs/binfmt_script.c中):對于shell腳本、Perl腳本等提供支持。寬松一點地說,所有前面兩個字符是“#!”的可執行文件,都歸由這個二進制處理程序進行處理。
這些Linux支持的二進制格式,可以在內核編譯鏈接的時候直接建立在內核之中,也可以在內核運行的時候作為模塊來加載。內核保存了支持的二進制格式解釋程序的列表,當試圖執行一個文件的時候,每一個二進制格式都會被依次嘗試,直到判斷出可識別的對應的二進制格式為止。
新聞熱點
疑難解答