Busybox1.13.3製作yaffs2根文件系統(靜態和動態)

準備工具1:mkyaffs2image

用途:用來製作目標文件系統映像。

工具2:busybox

用途:生成目標文件系統。網上有對它的介紹。

以上工具均來自友善之臂http://www.arm9.net/download.asp。交叉編譯工具arm-linux-gcc4.3.2。(在此衷心感謝資源、資料提供者)

製作過程:

選定 busybox-1.13.3.tgz這個版本, 以靜態方式編譯, 即生成的 busybox 不需要共享庫的支持就能運行。這樣做我們就不需要佈署程序庫了。缺點是自己寫的 arm-linux 程序在這個根文件系統中是不能運行的,因爲缺少共享程序庫的支持。不過不用擔心,通過在目標機裏以掛接 NFS 的方式, 將宿主機的 arm-linux-gcc 編譯器的庫文件掛到 arm-linux 的 /lib 下, 就可完美的運行我們自己的程序了。

現在開始製作靜態鏈接庫的根文件系統。

1、準備根文件系統

在機器上建立rootfs的文件夾

#mkdir rootfs

在rootfs中建立linux系統中典型的文件夾

#cd rootfs

#mkdir root home bin sbin etc dev usr lib tmp mnt sys proc

#mkdir usr/lib usr/bin

#pwd

/home/su/rootfs

2、解壓源碼包

#tar xzvf busybox-1.13.3.tgz

#cd busybox-1.13.3

3、修改 Makefile,

#vi Makefile

將Makefile中的

CROSS_COMPILE ?=

改爲

CROSS_COMPILE ?= arm-linux-

4、定製 busybox

選擇busybox下全部的可執行程序

#make defconfig

進到配置選項

#make menuconfig

設置靜態編譯方式

Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs)

Busybox Settings ---> Install Options ---> 中輸入建立根文件系統的文件所在的路徑/home /rootfs。

其它的默認。

確保 [*] Build BusyBox as a static binary (no shared libs) 被選中,保存退出

5、執行 make 編譯

#make

編譯通過, busybox 被生成了, 然後執行

#make install

busybox 就被安裝到指定的路徑下了/home /rootfs,這時可發現rootfs下多了個liunxrc的文件,bin、sbin下也多了很多文件。用ls –l命令查看其中的一個文件,可發現其是鏈接到busybox的一個連接符,所以我們之後在目標機上運行的命令大多都會調用busybox這個文件的。

若之前忘了指定路徑,默認生成到臨時目錄busybox-1.13.3/_install 下了。

6、編寫配置/etc下的初始化程序(可省略)

最簡單的做法是把busybox-1.9.2/examples/bootfloppy/etc下的全部文件拷到目標文件的etc目錄下

#cd /home/su/busybox-1.9.2/examples/bootfloppy/etc

#cp –rf * /home/su/rootfs/etc

也可自己寫這些文件。

7、把rootfs做成鏡像

#./mkyaffs2image 2 rootfs rootfs.yaffs2

8、把rootfs.yaffs2 燒寫到目標機中。

9、運行目標機

這時會遇到一個錯誤信息:

Can’t open tty2

Can’t open tty3

Can’t open tty4

解決辦法:把/rootfs/etc/ inittab 文件的第三行“tty2::askfirst:-bin/sh”刪除掉。

返回到第7步重做。

10、其他操作

1)用 chmod 777 linuxrc改變linuxrc屬性,否則可能無法執行。

2)運行時提示Warning :unable to open an initial console.

原來問題是,取消了Devfs後,不會自動生成設備了,也就沒有null和console,就不能啓動。解決方法:

在rootfs/dev/下:

mknod -m 660 null c 1 3

mknod -m 660 console c 5 1

OK了.

------------------------------------------------------------------------------------------

現實中,動態編譯的方法更適合工程的需要,所以一般是採用動態的方法編譯根文件系統的。若選擇動態編譯的辦法,大體方法還是一樣的,存在一些不同之處是:

不同之處之1是:

進到配置選項

#make menuconfig

選擇動態方式

Busybox Settings ---> Build Options ---> [*] Build Shared libbusybox

不同之處之2是(最大的不同之處):

編譯完成後,需進到rootfs目錄的lib中,往裏面添加一些庫文件

#cd /home/su/rootfs/lib

這裏有點麻煩,我怎麼知道需要什麼庫文件的支持呢?

最簡單的辦法是把arm-linux-gcc 3.3.2下的整個lib庫拷進來,簡單省事。但是這麼做存在一個問題,做出的根文件系統非常大。

另一個辦法是:

#cd /home/su/rootfs/bin

#arm-linux-readelf -d busybox | grep Shared

這樣就可以顯示出系統運行起來需要什麼庫文件,再把相應的庫文件拷到/home/su/rootfs/lib下。一般而言,系統庫用到兩個:動態鏈接器ld-linux.so和c函數庫Glibc,Glibc包括:

ld-linux:動態鏈接庫,必需

libc: 標準c函數庫,必需

libm: 數學庫,一般需要

libdl: 用於動態裝載共享庫,較少用到

libcrypt: 加密附加庫,需要認證的程序用到,較少用

libpthread: POSIX線程庫,一般需要

如果需要某個函數庫,我們可以將這些庫和對應的符號鏈接拷到目標根文件系統的/lib目錄下。簡單起見,應該使用-d選項或-a選項調用cp命令,這樣可保留完整的符號鏈接信息。

例:

#cp –a libc.so.6 /home/su/rootfs/lib/

爲了減少運行時庫的大小,我們應該使用交叉編譯版本即arm-linux-gcc 的strip工具來處理根文件系統的庫文件,把二進制文件中的包含的符號表和調試信息刪除掉。

例:

#arm-linux-strip /home/su/rootfs/lib/*.so

交叉編譯器4.3.2的lib哪裏覓??

之前將usr/local/arm/4.3.2/arm-non-linux-gnueabi/libc/lib下的*.so文件一股腦兒copy到rootfs/lib/下,結果下載後返回“Kernel panic - not syncing: Attempted to kill init!”出錯信息。後來終於想到可能是庫鏈接出問題,重新複製usr/local/arm/4.3.2/arm-non-linux-gnueabi/libc/armv4t/lib下的文件,問題解決!

後記:被動態編譯庫文件問題折磨了很久,希望本文對大家有點幫助。本文源於網友文章+自身實踐,在此未提供引用部分出處,見諒。

原文地址:http://hi.baidu.com/pingall/blog/item/d0ad750f3004dde7aa645768.htmlhttp://hi.baidu.com/pingall/blog/item/d0ad750f3004dde7aa645768.html

發佈了25 篇原創文章 · 獲贊 12 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章