胡 晉
同濟(jì)大學(xué)電信學(xué)院,上海 201804
Linux操作系統(tǒng)并不是專為嵌入式系統(tǒng)設(shè)計(jì)的,應(yīng)用于嵌入式設(shè)備時(shí)必須進(jìn)行裁剪優(yōu)化,其目的之一是為了簡(jiǎn)化已有的操作系統(tǒng)內(nèi)核的功能和結(jié)構(gòu),以滿足嵌入式系統(tǒng)對(duì)資源的限制需求。
嵌入式操作系統(tǒng)需要裁剪的對(duì)象主要有:引導(dǎo)及初始化程序,操作系統(tǒng)內(nèi)核,系統(tǒng)動(dòng)態(tài)加載模塊,動(dòng)態(tài)鏈接庫(kù)以及根文件系統(tǒng)等。定制裁剪的一般操作過(guò)程如下:獲取linux內(nèi)核、GNU utility等源代碼,根據(jù)項(xiàng)目需求和具體平臺(tái)對(duì)內(nèi)核源代碼進(jìn)行補(bǔ)丁操作,手工配置,去掉多余的功能模塊,保留部分開發(fā)調(diào)試用模塊和目標(biāo)功能模塊,生成配置文件。然后根據(jù)配置文件進(jìn)行自動(dòng)交叉編譯和鏈接,生成壓縮過(guò)的適合具體硬件平臺(tái)的內(nèi)核映像文件。再以同樣方式生成引導(dǎo)初始化程序映像和根文件系統(tǒng)映像,最后把三者通過(guò)適當(dāng)?shù)姆绞桨惭b到目標(biāo)開發(fā)板中,生成我們的目標(biāo)操作系統(tǒng),并且進(jìn)行功能和性能測(cè)試分析。
內(nèi)核裁剪方式有多種,有基于原內(nèi)核提供的kbuild體系的裁剪方法,有基于代碼分析的linux裁剪方法,有基于調(diào)用圖的linux裁剪方法?;诙涕_發(fā)周期的需求考慮,選擇采用kbuild體系的裁剪方法。Kbuild體系通過(guò)預(yù)定義一些變量(obj-m,obj-y)和目標(biāo)(bzImage),使內(nèi)核的編譯和擴(kuò)展變得十分方便,具有很強(qiáng)的可定制性。
可以有多種方式來(lái)建立交叉編譯環(huán)境,包括自行通過(guò)源碼編譯,通過(guò)外部工具進(jìn)行批處理編譯,本文采用開發(fā)板自帶的交叉編譯器。
原始內(nèi)核源碼包缺乏支持目標(biāo)開發(fā)板的模塊,需要打上由廠商所提供的補(bǔ)丁。
在內(nèi)核源碼目錄下的Makefile中修改指定內(nèi)核架構(gòu)和交叉編譯器,這樣就不需要在編譯時(shí)再指定了。
配置內(nèi)核有四種基本方式,有基于字符終端的也有在圖形界面下配置的。
make config 基于文本的最為傳統(tǒng)的配置界面,不推薦使用;
make menuconfig 基于文本選單的配置界面,字符終端下推薦使用;
make xconfig 基于圖形窗口模式的配置界面,Xwindow下推薦使用;
make oldconfig 如果只想在原來(lái)內(nèi)核配置的基礎(chǔ)上修改一些小地方,會(huì)省去不少麻煩。
以make menuconfig為例,選擇相應(yīng)的配置時(shí),有三種選擇,它們分別代表的含義如下:
Y-將該功能編譯進(jìn)內(nèi)核;
N-不將該功能編譯進(jìn)內(nèi)核;
M-將該功能編譯成可以在需要時(shí)動(dòng)態(tài)插入到內(nèi)核中的模塊;
配置過(guò)程需要使用空格鍵進(jìn)行選取。在每一個(gè)選項(xiàng)前都有個(gè)括號(hào), 但有的是中括號(hào)有的是尖括號(hào),還有一種圓括號(hào)。
用空格鍵選擇時(shí)可以發(fā)現(xiàn),中括號(hào)里要么是空,要么是"*",而尖括號(hào)里可以是空,"*"和"M"。這表示前者對(duì)應(yīng)的項(xiàng)要么不要,要么編譯到內(nèi)核里;后者則多一樣選擇,可以編譯成模塊。而圓括號(hào)的內(nèi)容是要你在所提供的幾個(gè)選項(xiàng)中選擇一項(xiàng)。
快速配置方法:make localmodconfig。Linux 2.6.32 開始引入了一個(gè)make localmodconfig用于簡(jiǎn)化kernel的配置。make localmodconfig會(huì)執(zhí)行l(wèi)smod命令查看當(dāng)前系統(tǒng)中加載了哪些模塊(Modules),將原來(lái)的配置文件中不需要的模塊去掉,僅保留前面lsmod出來(lái)的這些模塊,從而簡(jiǎn)化了內(nèi)核的配置過(guò)程。
這個(gè)方法的缺點(diǎn)是:僅能使編譯出的內(nèi)核支持已經(jīng)加載的模塊。因?yàn)樵摲椒ㄊ褂玫氖莑smod的結(jié)果,如果有的模塊當(dāng)前沒(méi)有加載,那么就不會(huì)編到新的內(nèi)核中。
配置完成后,保存退出,配置程序會(huì)自動(dòng)生成一個(gè)隱藏的配置文件.config,需要把這份文件另存到其他地方以便管理和使用。編譯內(nèi)核時(shí),源代碼目錄頂層Makefile文件讀取該目錄下的.config文件,得到內(nèi)核配置過(guò)程中所產(chǎn)生的編譯宏。Makefile根據(jù)這些使用編譯宏,決定所編譯的文件列表,并通過(guò)Rules.make使用公共規(guī)則產(chǎn)生相應(yīng)的目標(biāo)。
在GCC中,最常用的優(yōu)化選項(xiàng)是-Os,有-O0 -O1 -O2 -O3-Os。-O0關(guān)閉編譯器優(yōu)化,-O1是第一級(jí)優(yōu)化,編譯器將在不顯著增加編譯時(shí)間的基礎(chǔ)上,嘗試減少代碼尺寸,縮短執(zhí)行時(shí)間。使用-O2和-O3將增加優(yōu)化級(jí)別,同時(shí)仍然保留-O1所采取的優(yōu)化方法。-Os是介于-O2和-O3之間的優(yōu)化級(jí)別,使用-O3優(yōu)化可能造成不好的后果。
在內(nèi)核源碼目錄執(zhí)行下列命令,生成內(nèi)核鏡像文件。
生成的內(nèi)核鏡像位于源碼目錄的arch/arm/boot/,第一步命令生成的是zImage,是一般情況下默認(rèn)的壓縮內(nèi)核映像文件,通過(guò)壓縮vmlinux,再加上一段自解壓代碼生成。第二步命令是生成uImage,uImage是使用工具mkimage對(duì)普通zImage之前加上一段長(zhǎng)度為64字節(jié)的字段生成,說(shuō)明了該內(nèi)核的版本,加載位置,生成時(shí)間,內(nèi)核大小等信息,是ARM架構(gòu)專用的映像文件。
典型的嵌入式linux根文件系統(tǒng)具有幾個(gè)特征,其一是根文件系統(tǒng)中文件、庫(kù)和目錄,通常是經(jīng)過(guò)必要的選取和簡(jiǎn)化的,其二是根文件系統(tǒng)是經(jīng)過(guò)壓縮的,系統(tǒng)啟動(dòng)時(shí)解壓到內(nèi)存中。
嵌入式linux根文件系統(tǒng)制作工具BusyBox 是標(biāo)準(zhǔn) Linux 工具的一個(gè)單個(gè)可執(zhí)行實(shí)現(xiàn)。BusyBox 通過(guò)傳遞特定參數(shù)的方式來(lái)實(shí)現(xiàn)特定的linux工具和命令,提供超過(guò)200個(gè)Linux工具和命令的簡(jiǎn)化模式。
圖1 不同系統(tǒng)創(chuàng)建進(jìn)程比較
圖2 不同系統(tǒng)本地管道通信延遲比較
圖3 不同系統(tǒng)創(chuàng)建刪除10k文件系統(tǒng)時(shí)間比較
由于BusyBox也采用了ncurses工具,因此可以通過(guò)類似編譯內(nèi)核的配置方式:make menuconfig來(lái)進(jìn)行BusyBox的具體配置過(guò)程。配置過(guò)程中,可以在Makefile中具體指定ARCH和CROSS_COMPILE,安裝目錄,是否采用動(dòng)態(tài)編譯和需要哪些linux命令工具。
通過(guò)mkfs工具生成經(jīng)過(guò)壓縮的根文件系統(tǒng)鏡像jffs2.img。
將內(nèi)核鏡像文件uImage和根文件系統(tǒng)鏡像文件jffs2.img通過(guò)開發(fā)板工具載入開發(fā)板flash進(jìn)行功能測(cè)試,也可以在boot階段通過(guò)tftp來(lái)完成載入內(nèi)存工作。測(cè)量?jī)?nèi)核靜態(tài)體積大小,縮小到約原來(lái)的30%。
嵌入式linux操作系統(tǒng)成功啟動(dòng)。
通過(guò)對(duì)U盤,網(wǎng)卡等板上設(shè)備使用、C應(yīng)用程序運(yùn)行,操作系統(tǒng)命令運(yùn)行等進(jìn)行測(cè)試,結(jié)果正常。
lmbench具體通過(guò)內(nèi)存拷貝,內(nèi)存讀寫,管道,上下文切換,網(wǎng)絡(luò)連接的建立,文件系統(tǒng),進(jìn)程創(chuàng)建,信號(hào)處理,系統(tǒng)調(diào)用等參數(shù)來(lái)建立性能指標(biāo)體系。
在原來(lái)的嵌入式操作系統(tǒng)和目標(biāo)操作系統(tǒng)上運(yùn)行l(wèi)mbench100次,獲取有效數(shù)據(jù)進(jìn)行處理分析, 性能指標(biāo)選取有如下幾類:processes-time,pipe communication latencies,F(xiàn)ile create&delete latencies。比較各性能指標(biāo)平均數(shù)發(fā)現(xiàn),裁剪后的linux操作系統(tǒng)性能提升約5%~10%,穩(wěn)定性有一定提高。
隨著linux的發(fā)展,linux內(nèi)核的體積越來(lái)越大,通過(guò)優(yōu)化內(nèi)核體積和系統(tǒng)內(nèi)存占用,可以在一定程度上提升linux的性能表現(xiàn)。目前l(fā)inux的裁剪定制主要依賴于靈活的kbuild體系,通過(guò)條件編譯來(lái)實(shí)現(xiàn)。其他更細(xì)粒度的技術(shù)比如代碼分析技術(shù),調(diào)用圖技術(shù)還有待發(fā)展和成熟。
[1]Anand K Santhanam,Vishal Kulkarn.嵌入式設(shè)備上的linux系統(tǒng)開發(fā)[DB/OL].http://www.ibm.com/developerworks/cn/linux/embdev/samsung.com,2004,3.
[2]李紹勛,陳朔鷹,羅國(guó)良.linux2.6內(nèi)核測(cè)試及其到ARM嵌入式平臺(tái)的移植[J].理論和研究測(cè)試卷,2005(5).
[3]劉文峰,李程遠(yuǎn),李善平.嵌入式Linux操作系統(tǒng)的研究[J].浙江大學(xué)學(xué)報(bào):工學(xué)版,2004,38(4):447-452.
[4]馬永光,席亞賓,林永君.基于linux的嵌入式操作系統(tǒng)的研究[J].計(jì)算機(jī)世界網(wǎng),2003.
[5]鄭家玲,張?jiān)品?,嵌入式系統(tǒng)的內(nèi)核載入過(guò)程淺析[J].微型機(jī)與應(yīng)用,2002(11):59-60.
[6]TINYNew project home page of tiny:http://tinylab.org/index.php/projects/tinylinux.
[7]Karim Yaghmour.構(gòu)建嵌入式linux系統(tǒng).臺(tái)灣: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.