胡 晉
同濟大學電信學院,上海 201804
Linux操作系統并不是專為嵌入式系統設計的,應用于嵌入式設備時必須進行裁剪優化,其目的之一是為了簡化已有的操作系統內核的功能和結構,以滿足嵌入式系統對資源的限制需求。
嵌入式操作系統需要裁剪的對象主要有:引導及初始化程序,操作系統內核,系統動態加載模塊,動態鏈接庫以及根文件系統等。定制裁剪的一般操作過程如下:獲取linux內核、GNU utility等源代碼,根據項目需求和具體平臺對內核源代碼進行補丁操作,手工配置,去掉多余的功能模塊,保留部分開發調試用模塊和目標功能模塊,生成配置文件。然后根據配置文件進行自動交叉編譯和鏈接,生成壓縮過的適合具體硬件平臺的內核映像文件。再以同樣方式生成引導初始化程序映像和根文件系統映像,最后把三者通過適當的方式安裝到目標開發板中,生成我們的目標操作系統,并且進行功能和性能測試分析。
內核裁剪方式有多種,有基于原內核提供的kbuild體系的裁剪方法,有基于代碼分析的linux裁剪方法,有基于調用圖的linux裁剪方法。基于短開發周期的需求考慮,選擇采用kbuild體系的裁剪方法。Kbuild體系通過預定義一些變量(obj-m,obj-y)和目標(bzImage),使內核的編譯和擴展變得十分方便,具有很強的可定制性。
可以有多種方式來建立交叉編譯環境,包括自行通過源碼編譯,通過外部工具進行批處理編譯,本文采用開發板自帶的交叉編譯器。
原始內核源碼包缺乏支持目標開發板的模塊,需要打上由廠商所提供的補丁。
在內核源碼目錄下的Makefile中修改指定內核架構和交叉編譯器,這樣就不需要在編譯時再指定了。
配置內核有四種基本方式,有基于字符終端的也有在圖形界面下配置的。
make config 基于文本的最為傳統的配置界面,不推薦使用;
make menuconfig 基于文本選單的配置界面,字符終端下推薦使用;
make xconfig 基于圖形窗口模式的配置界面,Xwindow下推薦使用;
make oldconfig 如果只想在原來內核配置的基礎上修改一些小地方,會省去不少麻煩。
以make menuconfig為例,選擇相應的配置時,有三種選擇,它們分別代表的含義如下:
Y-將該功能編譯進內核;
N-不將該功能編譯進內核;
M-將該功能編譯成可以在需要時動態插入到內核中的模塊;
配置過程需要使用空格鍵進行選取。在每一個選項前都有個括號, 但有的是中括號有的是尖括號,還有一種圓括號。
用空格鍵選擇時可以發現,中括號里要么是空,要么是"*",而尖括號里可以是空,"*"和"M"。這表示前者對應的項要么不要,要么編譯到內核里;后者則多一樣選擇,可以編譯成模塊。而圓括號的內容是要你在所提供的幾個選項中選擇一項。
快速配置方法:make localmodconfig。Linux 2.6.32 開始引入了一個make localmodconfig用于簡化kernel的配置。make localmodconfig會執行lsmod命令查看當前系統中加載了哪些模塊(Modules),將原來的配置文件中不需要的模塊去掉,僅保留前面lsmod出來的這些模塊,從而簡化了內核的配置過程。
這個方法的缺點是:僅能使編譯出的內核支持已經加載的模塊。因為該方法使用的是lsmod的結果,如果有的模塊當前沒有加載,那么就不會編到新的內核中。
配置完成后,保存退出,配置程序會自動生成一個隱藏的配置文件.config,需要把這份文件另存到其他地方以便管理和使用。編譯內核時,源代碼目錄頂層Makefile文件讀取該目錄下的.config文件,得到內核配置過程中所產生的編譯宏。Makefile根據這些使用編譯宏,決定所編譯的文件列表,并通過Rules.make使用公共規則產生相應的目標。
在GCC中,最常用的優化選項是-Os,有-O0 -O1 -O2 -O3-Os。-O0關閉編譯器優化,-O1是第一級優化,編譯器將在不顯著增加編譯時間的基礎上,嘗試減少代碼尺寸,縮短執行時間。使用-O2和-O3將增加優化級別,同時仍然保留-O1所采取的優化方法。-Os是介于-O2和-O3之間的優化級別,使用-O3優化可能造成不好的后果。
在內核源碼目錄執行下列命令,生成內核鏡像文件。
生成的內核鏡像位于源碼目錄的arch/arm/boot/,第一步命令生成的是zImage,是一般情況下默認的壓縮內核映像文件,通過壓縮vmlinux,再加上一段自解壓代碼生成。第二步命令是生成uImage,uImage是使用工具mkimage對普通zImage之前加上一段長度為64字節的字段生成,說明了該內核的版本,加載位置,生成時間,內核大小等信息,是ARM架構專用的映像文件。
典型的嵌入式linux根文件系統具有幾個特征,其一是根文件系統中文件、庫和目錄,通常是經過必要的選取和簡化的,其二是根文件系統是經過壓縮的,系統啟動時解壓到內存中。
嵌入式linux根文件系統制作工具BusyBox 是標準 Linux 工具的一個單個可執行實現。BusyBox 通過傳遞特定參數的方式來實現特定的linux工具和命令,提供超過200個Linux工具和命令的簡化模式。

圖1 不同系統創建進程比較

圖2 不同系統本地管道通信延遲比較

圖3 不同系統創建刪除10k文件系統時間比較
由于BusyBox也采用了ncurses工具,因此可以通過類似編譯內核的配置方式:make menuconfig來進行BusyBox的具體配置過程。配置過程中,可以在Makefile中具體指定ARCH和CROSS_COMPILE,安裝目錄,是否采用動態編譯和需要哪些linux命令工具。
通過mkfs工具生成經過壓縮的根文件系統鏡像jffs2.img。
將內核鏡像文件uImage和根文件系統鏡像文件jffs2.img通過開發板工具載入開發板flash進行功能測試,也可以在boot階段通過tftp來完成載入內存工作。測量內核靜態體積大小,縮小到約原來的30%。
嵌入式linux操作系統成功啟動。
通過對U盤,網卡等板上設備使用、C應用程序運行,操作系統命令運行等進行測試,結果正常。
lmbench具體通過內存拷貝,內存讀寫,管道,上下文切換,網絡連接的建立,文件系統,進程創建,信號處理,系統調用等參數來建立性能指標體系。
在原來的嵌入式操作系統和目標操作系統上運行lmbench100次,獲取有效數據進行處理分析, 性能指標選取有如下幾類:processes-time,pipe communication latencies,File create&delete latencies。比較各性能指標平均數發現,裁剪后的linux操作系統性能提升約5%~10%,穩定性有一定提高。
隨著linux的發展,linux內核的體積越來越大,通過優化內核體積和系統內存占用,可以在一定程度上提升linux的性能表現。目前linux的裁剪定制主要依賴于靈活的kbuild體系,通過條件編譯來實現。其他更細粒度的技術比如代碼分析技術,調用圖技術還有待發展和成熟。
[1]Anand K Santhanam,Vishal Kulkarn.嵌入式設備上的linux系統開發[DB/OL].http://www.ibm.com/developerworks/cn/linux/embdev/samsung.com,2004,3.
[2]李紹勛,陳朔鷹,羅國良.linux2.6內核測試及其到ARM嵌入式平臺的移植[J].理論和研究測試卷,2005(5).
[3]劉文峰,李程遠,李善平.嵌入式Linux操作系統的研究[J].浙江大學學報:工學版,2004,38(4):447-452.
[4]馬永光,席亞賓,林永君.基于linux的嵌入式操作系統的研究[J].計算機世界網,2003.
[5]鄭家玲,張云峰,嵌入式系統的內核載入過程淺析[J].微型機與應用,2002(11):59-60.
[6]TINYNew project home page of tiny:http://tinylab.org/index.php/projects/tinylinux.
[7]Karim Yaghmour.構建嵌入式linux系統.臺灣:O'Reilly,2005:579-613.
[8]Greg Kroab-Hartman.Linux Kernel in a Nutsbell:O'Reilly,2010.
[9]G Gogniat,M auguin,L Bianco.A Codesign Back-End Approach for Embedded System Design.ACMTrans On Design Automation of Electronic System,2000,5:492-509.