導(dǎo)讀:前面《《基于Buildroot的Linux系統(tǒng)構(gòu)建之快速通關(guān)》》介紹了Buildroot構(gòu)建系統(tǒng)快速入手的一些基本操作,《《基于Buildroot直接進(jìn)行內(nèi)核配置》》主要介紹了在Buildroot中如何直接進(jìn)行內(nèi)核配置裁剪,作為嵌入式Linux,根文件系統(tǒng)的配置構(gòu)建除內(nèi)核之外最為復(fù)雜亦是最為重要的部分。本文分析記錄使用過程中的一些淺見,或有疏漏錯(cuò)誤之處,請(qǐng)交流指出,不勝感激。
1.根文件系統(tǒng)
通常而言文件系統(tǒng)是操作系統(tǒng)對(duì)存儲(chǔ)介質(zhì)(磁盤或閃存等)的進(jìn)行管理,實(shí)現(xiàn)存儲(chǔ)對(duì)象文件式的訪問管理的軟件。主要實(shí)現(xiàn)介質(zhì)管理、文件的讀寫訪問、應(yīng)用接口、權(quán)限管理等功能。當(dāng)然嚴(yán)格講這么描述是有問題,比如VFS虛擬文件系統(tǒng)。Anyway,這不是本文要討論的重點(diǎn),隨它去吧。引入只為理解方便。
那么何為根文件系統(tǒng)呢?它是一種文件系統(tǒng),其關(guān)鍵點(diǎn)在于這個(gè)“根”,是指內(nèi)核啟動(dòng)后加載的第一個(gè)文件系統(tǒng),內(nèi)核代碼映像保存在根文件系統(tǒng)中,而系統(tǒng)引導(dǎo)啟動(dòng)程序會(huì)在根文件系統(tǒng)掛載之后從中把一些基本的初始化腳本和服務(wù)等加載到內(nèi)存中去運(yùn)行。引自《《百度百科》》
下圖是Ubuntu的根文件系統(tǒng)樣式。
2.1 拷貝根文件系統(tǒng)骨架skeleton至$TARTGET_DIR
基本的Linux根文件系統(tǒng)是Unix文件夾目錄層次結(jié)構(gòu),skeleton是構(gòu)建根文件系統(tǒng)的基礎(chǔ)。
skeleton配置入口:
System configuration ---》Root FS skeleton
sekleton可以配置為默認(rèn)樣式
skeleton為于。/system/skeleton下:
inittab 的語法:
《id》::《runlevels》:《action》:《process》
id,用于指定串口控制臺(tái)名,需與實(shí)際對(duì)應(yīng),如為空則指/dev/console
runlevels,BusyBox不支持這個(gè)屬性,如設(shè)置則忽略
action:
sysinit,運(yùn)行當(dāng)init啟動(dòng)時(shí)在執(zhí)行其他操作之前的程序,如加載文件系統(tǒng)等
respawn,用于運(yùn)行程序并在終止時(shí)重啟這個(gè)程序,常用于控制一個(gè)程序以守護(hù)進(jìn)程運(yùn)行
askfirst,如其名(ask first then run),作用同respawn,不同的是需要用戶交互式確認(rèn),用戶需要輸入回車進(jìn)行運(yùn)行確認(rèn)。它用于在終端上啟動(dòng)交互式shell,而不提示輸入用戶名或密碼。
once,如其名,僅在開機(jī)啟動(dòng)時(shí)運(yùn)行一次所控制的程序,該程序終止后也不會(huì)重啟這個(gè)程序
wait,用于運(yùn)行程序并等待其完成后才執(zhí)行后續(xù)操作。如可以用這個(gè)命令運(yùn)行一些同步完成的操作。
restart,用于運(yùn)行當(dāng)init接收到SIGHUP信號(hào)時(shí)所需運(yùn)行的程序,并指示inittab需要重新加載
ctrlaltdel,用于當(dāng)init接收到SIGINT信號(hào)時(shí)所需要運(yùn)行的程序,中斷信號(hào)通常在啟動(dòng)階段會(huì)由Ctrl+Alt+Del發(fā)出。
shutdown,用于當(dāng)init接收到關(guān)機(jī)命令所需運(yùn)行的程序。這個(gè)是由于init進(jìn)程一直駐留后臺(tái)運(yùn)行。
process,上述action控制需要運(yùn)行的程序,如mount,swapoff等等。
2.1.2 systemV init
BusyBox是一個(gè)精簡(jiǎn)版本的systemV init系統(tǒng),想對(duì)于BusyBox,systemV init有兩個(gè)優(yōu)勢(shì):
首先,啟動(dòng)腳本是以模塊化格式編寫的使在構(gòu)建時(shí)或運(yùn)行時(shí)添加新軟件包變得容易。
其次,它具有運(yùn)行級(jí)別的概念,它允許啟動(dòng)一系列程序或從一個(gè)運(yùn)行級(jí)別切換到另一個(gè)運(yùn)行級(jí)別時(shí),立即停止。
支持8個(gè)運(yùn)行級(jí)別(0-6以及S級(jí)別):
各級(jí)別的作用:
S,運(yùn)行啟動(dòng)程序使用
0,停止系統(tǒng)
1-5,作為通用使用
6,重啟系統(tǒng)使用
2.1.3 systemd init
systemd 是于2010年由Lennart Poettering和Kay Sievers創(chuàng)建的一套集成工具,用于基于init守護(hù)程序管理Linux系統(tǒng)。包括設(shè)備管理(udev)和日志記錄等。systemd是最新技術(shù),并且仍在迅速發(fā)展。它在桌面和服務(wù)器Linux發(fā)行版中很常見。這里對(duì)具體機(jī)制細(xì)節(jié)不做描述,我也沒研究過。
2.2 構(gòu)建安裝軟件包
軟件包部署安裝一般包括以下一些步驟:
將構(gòu)建所有配置需構(gòu)建的目標(biāo)軟件包
如Busybox,Qt,OpenSSH,lighttpd等
其中大多數(shù)將在$(TARGET_DIR)中安裝文件:程序,庫(kù),字體,數(shù)據(jù)文件,配置文件等。
2.3 運(yùn)行cleanup
這一步咋一看不明所以,為啥要清理。安裝完所有軟件包后,將執(zhí)行清除步驟以減小根文件系統(tǒng)的大小。主要涉及:
刪除頭文件,pkg-config文件,CMake文件,靜態(tài)庫(kù),手冊(cè)頁和說明文件。
使用strip剝離所有程序和庫(kù),以刪除不需要的信息。
取決于BR2_ENABLE_DEBUG和BR2_STRIP_ *選項(xiàng)。
其他特定的清理步驟:使用Python時(shí)清理不需要的Python文件等。請(qǐng)參閱Buildroot代碼中的TARGET_FINALIZE_HOOKS。
2.4 拷貝根文件系統(tǒng)覆蓋
要自定義根文件系統(tǒng)的內(nèi)容,如添加配置文件,腳本,符號(hào)鏈接,目錄或任何其他文件,一種可能的解決方案是使用根文件系統(tǒng)重載。
根文件系統(tǒng)覆蓋只是一個(gè)目錄,在安裝了所有軟件包之后,其內(nèi)容將復(fù)制到根文件系統(tǒng)中。允許覆蓋文件。
選項(xiàng)BR2_ROOTFS_OVERLAY包含以空格分隔的疊加路徑列表。
那么實(shí)際操作咋整?可以將默認(rèn)構(gòu)建的根文件系統(tǒng)掛載進(jìn)行調(diào)試,如需要修改某部分的內(nèi)容修改好,并將該文件夾拷貝出來,在Buildroot配置項(xiàng)將重載開啟,重載路徑指向該文件夾,Buildroot將在構(gòu)建過程中自動(dòng)復(fù)制該內(nèi)容覆蓋對(duì)應(yīng)的部分。
2.5執(zhí)行post-build腳本
如根文件系統(tǒng)覆蓋還不夠滿足要求,此時(shí)可以考慮使用post-build腳本來做補(bǔ)充,常常用來完成下面類似的需求:
可用于自定義現(xiàn)有文件,刪除不需要的文件以節(jié)省空間,添加動(dòng)態(tài)生成的新文件(構(gòu)建日期等)
在創(chuàng)建根文件系統(tǒng)映像之前執(zhí)行。 可以用任何語言編寫,經(jīng)常使用shell腳本。
BR2_ROOTFS_POST_BUILD_SCRIPT包含以空格分隔的后生成腳本路徑列表。
$(TARGET_DIR)路徑作為第一個(gè)參數(shù)傳遞,其他參數(shù)可以在BR2_ROOTFS_POST_SCRIPT_ARGS選項(xiàng)中傳遞。
相關(guān)的環(huán)境變量:
BR2_CONFIG,Buildroot.config文件的路徑
HOST_DIR,STAGING_DIR,TARGET_DIR,BUILD_DIR,BINARIES_DIR,BASE_DIR
關(guān)于根文件系統(tǒng)還有權(quán)限表、用戶表、設(shè)備表、設(shè)備管理以及映象文件如何部署等.
評(píng)論