![]() |
| 新浪首頁 > 科技時代 > FreeBSD使用大全連載 > FreeBSD連載(57):可執行程序格式 |
![]() |
可執行程序格式在FreeBSD下的可執行程序通常可分為兩類,一類為使用各種解 釋語言編寫的腳本,如sh、awk、perl、Tcl等,這些程序需要解釋程序 進行解釋執行,小巧方便,對于實現不常使用、不要求效率的程序非常 有用﹔另一類就是使用C等高級語言編譯后產生的可執行二進制程序。 Unix之所以功能強大,原因之一就在于它提供了強大的再開發 能力。這不僅與提供了高級語言C的編譯器有關,而且也與提供了很多 種能以解釋方式執行的簡單腳本語言有關。解釋程序腳本的特點是方便 性、簡單靈活,而且也比較容易學習入手。很多情況下,需要完成的工 作任務功能比較單一,并不需要頻繁運行,而且要求快速編寫出來,這 就適合使用解釋型語言編寫,并且解釋程序本身就具備處理文本和字符 串的便捷性,并能夠和很多現有程序通過系統提供的管道、環境變量等 方式結合起來,使得它們非常適合實現文本處理功能。 解釋語言的缺點是每次運行程序時都要載入語言的解釋器,解釋 執行程序,因而效率較低,并且不能直接操縱內存和I/O設備,不適合編 寫大型程序和對效率要求較高的場合。 每個解釋腳本程序的第一行指出該腳本程序使用的解釋器,例如 一個普通的shell程序的第一行為:
不同的解釋語言可用在不同的方面,最常用的有shell解釋程序, 依據使用shell的不同,也分為不同的shell腳本,基本上也分為sh和csh 兩種不同的風格。系統管理中經常使用shell程序來執行一些日常管理任 務,很多軟件也使用shell程序來提供輔助安裝和設置任務。perl也是一 種常用的、功能強大的解釋語言,它兼有解釋性程序的方便性和高級編 程語言的強大功能,使程序員能在很短的時間內寫出非常有效的程序。 因此perl得到了眾多程序員的支持,通過為perl開發了更多的程序模塊 ,進一步使得perl的處理能力變得更為強大。當前perl已經成為了最流 行的一種解釋語言,尤其在編寫Web服務器上的CGI程序方面,更是處于 無可爭議的地位。Tcl/tk是另一種解釋語言,它能用在X Window系統下 ,使用描述語言顯示不同的X控件,因此很多X應用程序使用它來建立自 己的圖形接口。
使用高級語言編寫、并經過編譯得到的二進制執行程序執行效率 更高,并且只有二進制格式的執行文件才能充分利用Unix系統提供的全部 功能。同樣系統內核也是一個特殊格式的二進制執行文件。 早期的Unix使用a.out格式作為它的執行文件格式,隨著Unix的發 展,又出現了其他几種執行文件的格式,當前最重要的執行文件格式為ELF 格式,采用這種格式的最初想法是為了在不同平台間采用相同的執行文件 格式,并實現動態共享連接庫。雖然ELF文件格式并沒有達到AT&T最 初設想的全部目的,但這種文件格式卻成為最流行的執行文件格式。除此 之外,實際使用的文件格式還有一種較老的COFF格式,這種格式是在Unix System V R3.2中使用的,當前只有老版本的SCO Unix中還在使用它,而 SCO也正逐漸轉向ELF格式。 FreeBSD可以同時支持這兩種執行文件的格式,FreeBSD 2.2.x之前 的版本使用a.out格式作為缺省的執行文件格式,到FreeBSD 3.x之后ELF格 式成為缺省的執行文件格式,并且以后會徹底轉向ELF。事實上在FreeBSD 下的a.out格式具備了相當多的特性,如動態連接等ELF格式具備的特性, 也有一些ELF格式不具備的特性,如壓縮執行文件格式。但由于FreeBSD中 使用的編譯器gcc決定不再支持a.out格式的緣故,因此FreeBSD也必須轉向 ELF格式。這也是當前還支持a.out格式的FreeBSD版本缺省使用較老版本編 譯器的原因之一。 在FreeBSD中,a.out格式的執行文件可以支持壓縮執行格式,這使 得使用gzip壓縮過的a.out格式的執行文件也能立即執行,當前還不能對ELF 格式的文件提供這種支持。 FreeBSD的文件格式從aout到ELF的轉變是漸變的,首先是在3.0-RELEASE 中將執行程序的缺省格式轉變為ELF格式,內核文件還保持aout格式,直至 FreeBSD-3.1,全部執行文件格式才缺省設置為ELF格式。 轉向ELF也造成很多相關程序的轉變,如原有的Boot Loader不支持 ELF格式的內核,3.1-RELEASE就升級到新Boot Loader﹔而原有的可加載模 塊lkm為aout格式,也需要轉向ELF格式的modules。新可加載模塊的位置為 /modules目錄,并使用kldload、klduload、kldstat來進行管理。(aout格 式的模塊管理命令為modload、modstat和modunload)。 a.out和ELF格式使用的庫文件也是不同的,使用ELF執行文件格式的 FreeBSD 3.x中,/usr/lib下為ELF格式的函數庫,而用一個子目錄/usr/lib/aout 存放a.out格式的函數庫,用于兼容2.2.x之前版本的FreeBSD程序。但這給一 些使用包裝技朮的軟件(一些中文外挂系統)造成了一些小麻煩。對不同格 式的執行文件要使用不同的包裝庫,系統不會將與程序本身格式不同的連接 庫連接到程序上,對應的錯誤信息為 “bad magic”,指出文件格式的不同。 由于3.x之后的缺省格式為elf格式,為了生成a.out格式的文件,必須 在編譯和連接時使用 -aout參數,告訴編譯器gcc和連接器ld使用不同的格式 生成執行文件。
在操作系統發展的早期,除了內核提供的接口,所有的庫函數都要 連接到程序中,這樣所有的程序都可以直接在系統內核下運行。然而事實上 大部分程序都會使用一些相同的庫函數,尤其是在使用高級語言編程的時候 ,通常都使用同樣的庫。例如,C語言編寫的程序通常都使用printf函數進行 輸出,使用scanf讀入用戶輸入內容。如果每個庫函數都連接到用戶程序中, 這樣每個程序都會包括這個函數的一個拷貝,就浪費了內存空間。 因此,現代操作系統使用動態連接的技朮,不將常用的庫直接編譯進 每個程序中,而是保留相應的接口,在內核載入程序時,再使用動態連接程 序將庫載入并和執行程序連接起來。這就是動態連接的技朮,由于庫和程序 是分別載入的,因此多個程序可以共享一個庫的同一個拷貝,節約了資源。 不論對于a.out格式還是ELF格式,FreeBSD均支持動態連接,因此應用 程序缺省就使用動態連接的方式。如果想使用靜態連接,可以在應用程序編譯 連接時,指定-static連接選項,將目標程序連接成靜態連接的執行文件。由于 庫代碼被連接進執行文件中,靜態連接的執行文件要比動態連接的執行文件要 大。
在FreeBSD下,共享庫被放到/etc/ld-config設定的目錄下,通常為 /usr/lib,每個庫文件使用.so和庫的版本號結尾。例如,libc.so.3.1為一個 標准C庫函數的動態共享庫文件。對于a.out格式的執行文件,其動態庫文件位 于/usr/lib/aout目錄下。 可以使用程序ldd來確定一個程序使用的動態連接庫:
很多其他Unix系統,例如BSD/OS和Linux,也是運行在Intel平台上的 系統,那么執行程序中的處理器指令是完全相同的,不同之處只在于應用程序 的格式、應用程序與操作系統的接口、庫文件等。事實上由于同為Unix系統, 這些差異也很小,因此通過調整內核的一些參數設置,FreeBSD完全可以直接 運行這些系統下的執行程序。 FreeBSD能夠同BSD/OS、NetBSD和OpenBSD的Intel平台上的應用程序相 兼容,同為BSD家族的成員,他們非常類似。NetBSD、OpenBSD和FreeBSD同為 免費系統,并且具有同樣的起源,與FreeBSD的關系非常密切,因此FreeBSD能 直接運行NetBSD和OpenBSD的Intel平台下的執行程序。然而NetBSD和OpenBSD 也是自由操作系統,因此它們中的應用程序也會有相應的FreeBSD版本,因此這 個功能一般很少用到。BSDI是一個商業公司,因此會提供BSD/OS下的二進制執 行文件,但不提供源代碼。FreeBSD能夠完美的運行BSD/OS下的a.out格式的執 行文件,ELF執行格式的程序也能執行,但偶爾會有問題發生,因此就需要調整 系統設置。 FreeBSD也能夠執行SCO Unix的執行文件,這需要使用內核的ibcs2( Intel binary compatibility system 2)選項。這需要載入一個內核可加載 模塊,這需要使用root身份執行ibcs2命令以載入ibcs2模塊。
可以在rc.conf中設置 “ibcs2_enable=YES” ,使開機后立即載入這 個模塊。 但是要執行SCO的應用程序,僅有內核支持還是不夠的,還需要有SCO Unix的函數庫。但SCO Unix的庫函數是SCO Unix的一部分,受版權保護的。如 果使用者擁有合法的SCO共享庫和應用程序,就可以運行SCO Unix上的大型商業 應用程序。 同樣,FreeBSD也能夠運行Linux的可執行程序,與執行SCO程序類似, 這也要求內核支持并載入相應的模塊。rc.conf中的相應參數為 “linux_enable” 。
但是與SCO不同的是,Linux是一種自由操作系統,其庫函數為GNU開發 的函數庫,使用GNU通用許可保護自由使用的權利。因此FreeBSD在Packages Collection中提供了Linux的共享庫,安裝了這些Linux的庫函數之后,就可以 執行Linux的執行程序了。
FreeBSD也能執行Solaris x86和SCO Unixware的ELF格式執行程序,只 是這個功能還沒有加入正式發行版本。同樣,這也需要相應的系統動態連接庫 文件,但是這些庫是商業產品,因此使用起來就會受到限制。
在運行Linux應用程序時,會遇到一些程序不能正確執行的情況,很多 情況下并不是FreeBSD本身的問題,而是由于系統的設置不正確造成的,必須作 一些設置和調整。 由于Linux使用Elf文件格式,有些時候FreeBSD不能分清一個ELF執行文件 是那種系統的執行文件,而誤認為是FreeBSD的執行文件,導致不能正確執行程 序。此時就需要使用brandelf命令來指定需要執行的ELF執行文件的類型,Linux 的ELF執行文件為Linux:
另一種差異是系統文件名字的差異,例如Linux的加密口令文件為shadow, 而FreeBSD使用master.passwd,Linux的控制台終端設備文件為/dev/tty0,FreeBSD 為/dev/ttyv0,對于一些要使用這些系統文件的應用程序,就造成無法正確讀取相 應文件的問題,這種情況可以使用符號連接來解決。
此外,Linux動態連接庫的版本不合適,也是很多Linux程序不能正常運行 的主要原因。Linux使用GNU開發的glib作為庫函數,編譯器gcc首先實現了glibc1 ,用于兼容標准的C庫函數libc5。隨著gcc的發展,它發展到了glibc 2,也被稱 為libc6。這兩個不同版本的庫有一定的差異,glib2功能更強,但由于出現時間 還短,不是所有的Linux版本都使用glibc2。有的Linux版本還在使用glibc1,如 Slackware 3.6,而另一些Linux如RedHat 5.0,Debin 2.0都使用glibc2,因此運 行Linux應用程序的時候,首先就要確認其使用的C庫函數版本。除了標准的C庫之 外,Linux應用程序使用的其他動態連接庫也會存在不一致的問題。 因此如果Linux應用程序使用的庫和FreeBSD安裝的Linux共享庫版本不一 致,那么就不會正常執行這些Linux程序。Linux是一個非常活躍的開發系統,某 些版本的Linux常常等不及系統穩定就將應用程序及其使用的庫升級,因此為了運 行要求新動態連接庫的Linux應用程序,就必須及時更新Linux的共享庫。除了及 時更新FreeBSD正式發行的Linux共享庫(這個共享庫通常為一個穩定版本,不會 一味求新)之外,為了跟上Linux升級的腳步,還必須手工安裝Linux的庫和其他 執行文件。 當前FreeBSD提供的Linux動態連接庫為Linuxlib-2.6,提供了對glibc2庫 及其他一些共享庫的支持,然而眾多的應用程序還會使用其他各種動態連接庫。 FreeBSD的軟件庫只能支持常用的Linux應用程序,為了徹底解決Linux應用程序的 動態連接庫更新問題,并不能依靠FreeBSD提供的軟件包。還是應該使用Linux的 方式,按照Linux的方式安裝所需要的Linux動態連接庫。 FreeBSD下用于與Linux相兼容的程序和庫文件統統位于/usr/compat/linux 目錄下(根目錄下有它的一個連接/compat/linux,compat目錄為兼容其他系統執 行文件的目錄),為了安裝新的Linux文件,首先要將這個目錄清除。
安裝新的Linux兼容文件可以通過多種方式來完成,由于當前最流行的 Linux系統通常使用RPM的包管理方式,因此可以使用RPM包來安裝Linux文件。這 需要首先安裝包管理程序rpm,這個程序有FreeBSD版本(此時還無法運行Linux程 序)。可以在Packages Collection中找到這個軟件。 然后就要為安裝Linux的RPM包初始化rpm,使rpm不使用根目錄作為系統的 起始路徑,而使用/usr/compat/linux作為所有的rpm包的根進行安裝,這就要使 用 --root參數指定相對的根目錄,以將Linux執行程序與FreeBSD執行執行程序 區分開。rpm在/usr/compat/linux/var/local/lib/rpm中記錄包的安裝信息。
當使用rpm -I安裝好所有必須的系統支持文件,以及需要執行的應用程序, 這樣安裝完畢之后,在通過調整一些參數,Linux程序就能正常執行了。主要需要根 據應用程序的錯誤提示,修改FreeBSD和Linux在文件和目錄結構上的不同,如Linux 執行程序的位置,應該更改為/usr/compat/linux/usr/bin目錄或其他相應的路徑, 而非原有根目錄下的路徑,以使得Linux程序內部只調用Linux執行程序。只有一些 對執行程序的格式不敏感的程序,可以使用/bin或/usr/bin下的相應FreeBSD執行程 序。通過這樣的設置之后,在FreeBSD下就能運行包括Oracle 8 for Linux在內的大 型應用軟件。 但是FreeBSD并不可能運行所有的Linux程序,有的應用程序程序對Linux內核 有一定要求,需要內核的特定版本的支持。一般來講,對于這些對Linux特定內核有要 求的應用程序,FreeBSD也就無法提供支持了。 不管怎樣,雖然在FreeBSD下運行Linux執行程序沒有太大的問題,然而畢竟 Linux是一個獨立的操作系統,處理問題的風格與FreeBSD不同,因此除了較小的程序 之外,安裝支持文件、必要的目錄結構等參數的調整是免不了的。 未完,待續。。。 |
|||||||||||||
| 新浪首頁 > 科技時代 > FreeBSD使用大全連載 > FreeBSD連載(57):可執行程序格式 | ||||||||||||||
Copyright(C) 1999 SINA.com, Stone Rich Sight. All Rights Reserved
版權所有 四通利方 新浪網