| 使用BusyBox, 在為目標系統(tǒng)所構(gòu)建的根文件系統(tǒng)中添加應(yīng)用程序就易如反掌了. 想象一下:單獨得交叉編譯每個UNIX/Linux應(yīng)用程序的工作量是多么恐怖. |
BusyBox 可以與glibc或uClibc庫進行鏈接編譯, 可以采用動態(tài)鏈接或靜態(tài)鏈接(配置選項中可選).即便采用與glibc的靜態(tài)鏈接,最終生成的busybox文件大小也能輕易控制在1MB之內(nèi)(在配置BusyBox時不要選擇不需要的功能).而采用uClibc動態(tài)鏈接的可執(zhí)行文件就更小了. 這非常適于存儲空間緊張的嵌入式Linux系統(tǒng). 由此,有人將BusyBox稱為嵌入式系統(tǒng)中的瑞士軍刀. 更為形象的比喻是: Linux系統(tǒng)中的單個命令是電路中的分立式元件,而BusyBox是將它們集成在一起的IC: 功能不變, 體積卻大為減小.
本文討論BusyBox的編譯, 安裝. 包括安裝到本地主機和安裝到ARM目標系統(tǒng)中.
配置BusyBox
配置BusyBox和配置Linux內(nèi)核的方法很類似, 思想也大同小異: 也是基于源碼樹目錄中的.config文件來進行的.還是推薦使用menuconfig配置工具.
下面的工作都是在解壓后的BusyBox源碼樹根目錄中進行的.
$ makedefconfig: 針對大多數(shù)用戶的默認配置
$ makeallnoconfig: 全不選
$ makeallyesconfig : 全選
一般先make deconfig, 然后再使用menuconfig進行配置.
| $ make help查看BusyBox的make選項幫助. |
如同配置Linux內(nèi)核, 你也可以使用既有的.config(可更改其命名)文件. 可以在menuconfig中加載,輸出配置文件.
下面列出一些值得注意的配置選項:
BusyBoxSettings
BuildOptions:
Build BusyBox as a staticbinary (no shared libs) : 將BusyBox動態(tài)鏈接或靜態(tài)連接.
- Do you want to buildBusyBox with a Cross Compiler? : 選擇交叉編譯器.

InstallationOptions:
默認地, 運行 make install之后, BusyBox將被安裝到./_install目錄.
配置根據(jù)具體需要來: 不需要的不選.
- NFS是肯定要選的, 使用NFS將宿主機的文件系統(tǒng)mount到目標板上,這是嵌入式Linux程序開發(fā)的一個重要方面.
- 由于可使用NFS, 能在宿主機上實現(xiàn)的功能就都不需要在目標板上實現(xiàn)了.
- Debian Utilities 全不選, Editors全不選, System LoggingUtilities全不選.
- 解壓縮工具只安裝解壓工具. 而且只選擇一種: bzip2相關(guān)的,以及tar工具(只要求目標板能解壓縮tar.bz2文件).
- shell使用ash.
編譯BusyBox
完 成對BusyBox的配置工作后, 就可以編譯, 安裝它了. BusyBox可用于多種體系結(jié)構(gòu)的CPU.這里分別介紹用于本機系統(tǒng)的BusyBox和用于ARM目標系統(tǒng)的BusyBox. 另外,BusyBox可與glibc或uClibc動態(tài)或靜態(tài)連接. 下面分情況介紹:
用于本機的BusyBox
用于本機的BusyBox編譯過程很簡單, 只需運行make就可以了.
交叉編譯BusyBox
交叉編譯BusyBox與編譯用于本地系統(tǒng)的BusyBox大同小異, 唯一的區(qū)別是它需要使用交叉編譯工具. 另外要注意庫的鏈接方式:如果目標系統(tǒng)中沒有某庫, 那么BusyBox應(yīng)該與該庫靜態(tài)鏈接. 編譯步驟如下:
1, 修改PATH變量:
$ exportPATH=<交叉編譯工具所在目錄>:$PATH
2, 在調(diào)用make命令時候要指定TARGET_ARCH和CROSS變量.
$ make TARGET_ARCH=armCROSS=arm-linux-
| 新版的BusyBox可以在配置過程中設(shè)定交叉編譯工具. 這樣,為目標系統(tǒng)編譯BusyBox的make命令和為本地主機編譯BusyBox沒有任何區(qū)別! |
我這里使用Scratchbox來針對ARM目標系統(tǒng)編譯BusyBox. (可參考本blog的:使用Scratchbox來開發(fā)嵌入式Linux).安裝scratchbox之后, 可以在對scratchbox進行配置時安裝各種交叉編譯工具:arm-linux-gcc(與glibc鏈接),arm-linux-uclibc-gcc(與uclibc鏈接),它還可以為本地系統(tǒng)(x86)安裝與uclibc鏈接的gcc. 這樣你直接指定相應(yīng)的編譯器既可.不需要另外安裝uClibc庫.
| 為了加快編譯速度, 可以修改Makefile, 將CC="$(HOSTCC)"改為CC="ccache $(HOSTCC)".同時也可使用 $ make -j2用2個任務(wù)來進行編譯過程. |
實例
下面以幾個例子來介紹BusyBox的編譯方法:
1,針對本地主機編譯與glib鏈接的BusyBox
由于GNU/Linux系統(tǒng)中都裝有g(shù)libc, 所以可以不使用Scratchbox提供的編譯器. 而且,可以將BusyBox配置為與glibc庫動態(tài)鏈接. 其他選項均設(shè)為默認.
$ makedefconfig; 默認配置
$ makemenuconfig ; 選擇與glibc動態(tài)鏈接
$ make-j2
$ make install
可以使用ls -l, file命令查看生成的busybox可執(zhí)行文件相關(guān)信息. 注意,在源碼樹根目錄同時還生成了busybox_unstripped文件, 將它strip之后即得到busybox.
默認配置, 與glibc動態(tài)連接后的busybox大小為: 858K
2, 針對本地主機編譯與uClibc鏈接的BusyBox
我 沒有另外地在本地主機上安裝uClibc, 而是使用Scratchbox提供的編譯工具:i386-gcc-3.3.2-uclibc-snapshot-20040229. 由于本地主機上沒有uClibc庫,所以將busybox與uClibc庫靜態(tài)鏈接. 其他選項設(shè)為默認
$ export PATH=/home/zp/project/sb/scratchbox/compilers/i386-gcc-3.3.2-uclibc-snapshot-20040229/bin:$PATH
$ makemenuconfig
$ makeCROSS=i386-linux-uclibc--j2
$ makeinstall
默認配置, 與uClibc靜態(tài)鏈接后的busybox大小為: 1.1M
3,針對ARM目標系統(tǒng)編譯與glibc動態(tài)連接的BusyBox
使用Scratchbox中提供的arm-linux-gcc交叉編譯工具. 這里沒有使用默認配置,而是只選擇我認為需要的功能.
$ exportPATH=/home/zp/project/sb/scratchbox/compilers/arm-linux-gcc3.4.cs-glibc2.3/bin:$PATH
$ makemenuconfig
$ make CROSS=arm-linux--j2
$ makeinstall
剔除了不需要的內(nèi)容, 與glibc動態(tài)鏈接后的busybox大小為: 382K
4,針對ARM目標系統(tǒng)編譯與uClibc靜態(tài)連接的BusyBox
使用Scratchbox中提供的arm-linux-uclibc-gcc交叉編譯工具. 這里沒有使用默認配置,而是只選擇我認為需要的功能.
$ exportPATH=:/home/zp/project/sb/scratchbox/compilers/arm-linux-gcc3.4.cs-uclibc0.9.27/bin$PATH
$ makemenuconfig
$ make CROSS=arm-linux-uclibc-j2
$ makeinstall
剔除了不需要的內(nèi)容, 與uClibc靜態(tài)鏈接后的busybox大小為: 509K
| 注意: 針對ARM目標系統(tǒng)編譯BusyBox時, 可在menuconfig中選擇特定的交叉編譯器.這樣就make命令就和為本地主機編譯BusyBox一樣了, 不需要更改PATH和CROSS變量. |
安裝,運行BusyBox
編譯完成后, 輸入 $ makeinstall 進行BusyBox的安裝.
默認地, BusyBox將在當前目錄(也就是BusyBox源碼樹根目錄)新建一個名為"_install"的目錄.BusyBox將被安裝到其中. 可以在配置BusyBox時設(shè)定安裝目錄.
完成安裝之后, 在./_install目錄中有下列文件和目錄:
binlinuxrc sbin usr
其 中l(wèi)inuxrc, bin, sbin, usr目錄中的包含一些我們熟悉的位于PC機/bin, /sbin, /usr/bin,/usr/sbin目錄中的程序.而BusyBox安裝的這些程序都是指向busybox文件(位于./_install/bin目錄)自身的符號連接.
運行BusyBox"安裝"的這些程序時候, 實際上都是在調(diào)用busybox這個單獨的程序. 比如: $ ./ls -l , 實際向busybox傳遞了2個參數(shù): ls和-l. 前面的命令等價于$ ./busybox ls-l.
針對前面編譯實例中安裝的BusyBox,我們分別討論針對本地主機編譯的BusyBox和針對ARM目標系統(tǒng)編譯的BusyBox.
本地主機
很簡單, 可以直接調(diào)用busybox, 也可以調(diào)用連接到它的符號連接. 當然, 可以修改PATH變量來直接調(diào)用它們.
$ ./busybox ls -l
$ ./ ls -l
ARM目標系統(tǒng)
可以使用仿真工具來運行. 這里使用qemu. 在Debian/Ubuntu中安裝qemu: $ sudo apt-get install qemu
$ qemu-arm ./busybox ls-l
這里有個問題, 如果busybox是與C庫動態(tài)鏈接的(哪怕是和glibc庫動態(tài)鏈接), 那么運行它是將會產(chǎn)生段錯誤:
Unable to loadinterpreter
Segmentation fault (coredumped)
如果采用靜態(tài)鏈接, 則沒有問題.
| BusyBox還提供與init類似的功能, 也非常適用與嵌入式系統(tǒng). |
參考資料
1, http://www-128.ibm.com/developerworks/cn/linux/l-busybox/index.html
2, 《構(gòu)建嵌入式Linux系統(tǒng)》第6章.
3, http://free-electrons.com/training/devtools
4, busybox命令: http://www.busybox.net/downloads/BusyBox.html
愛華網(wǎng)



