本文介紹如何利用busybox製作一個最小根文件系統,系統包含ls、cd、ifconfig等基本指令,文件系統採用動態加載的方式。
1.去busybox官網下載源碼
- 官網地址:busybox官網
- 下載busybox-1.29.0版本。
2.將源碼拷貝至Linux主機並解壓
將busybox源碼拷貝到linux主機並解壓,同時新建一個rootfs文件夾,用於保存待會製作好的根文件系統。
3.配置makefile
進入busybox源碼主目錄,首先配置makefile文件:
- cd busybox-1.29.0
- vim makefile
makefile需要改的就是指定處理器架構和交叉編譯器。
4.配置busybox
- make menuconfig
首先是setting
接下來是Linux Module Utilities配置
接下來是 Linux System Utilities配置
write support 下面的6個子選項需要全部勾上。
最後是shell配置:bash shell和sh 最終都解釋爲ash運行
以上配置完成以後,保存退出。
5.編譯busybox
- make
在源碼根目錄下執行make編譯:
出現了錯誤,提示setns和syncfs未定義,出現這兩個錯誤的原因就不分析了,由於這兩個文件對於根文件系統的影響微乎其微,所以我們在menuconfig裏把這兩個地方屏蔽掉就可以了。
然後保存退出,繼續編譯。
6.安裝文件系統
- make install CONFIG_PREFIX=/test/rootfs/
CONFIG_PREFIX是指定文件系統安裝位置,這裏指向我們剛剛新建的rootfs文件夾
安裝完成,我們去rootfs文件夾看下:
多了這4個文件(夾),至此busybox的任務就完成了。但是這個根文件系統是不完整的,還缺少很多東西,所以接下來我們就需要完善這個根文件系統。
7.構建lib目錄
由於我們在menuconfig裏選擇的是動態庫,所以我們需要構建需要的動態庫文件(.so文件)。
這些動態庫文件在交叉編譯器的目錄下可以找到,我們直接把整個lib複製過來。
- mkdir lib
- cp /ZLG_linux/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/arm-fsl-linux-gnueabi/multi-libs/lib/* /test/rootfs/lib/ -a
注意複製的時候要選擇-a,因爲lib下有很多鏈接文件,我們需要將鏈接文件和鏈接文件的源文件都複製過來。
由於我的lib庫裏自帶了很多靜態庫文件,這些靜態庫文件是不需要的而且佔用很大空間,所以需要將它們刪除:
- rm -f *.a
我們可以看下lib文件的大小:
有7.6M,這個lib文件還是比較大的,因爲裏面有很多用不到的庫,我們也一併複製過來了,但是影響不大。
注意:也可以在lib下使用arm-fsl-linux-gnueabi-strip *去掉lib裏面庫文件的符號文件 對庫文件進行瘦身(去除符號表和調試信息)
至此,lib文件就構建完成了。
8.構建etc目錄
我們可以把/busybox-1.29.0/examples/bootfloppy下的etc目錄直接拷貝過來。
在配置etc目錄之前首先簡單講下文件系統的啓動順序:
- Linux內核啓動過程中,運行的第一個程序是init程序,通常是根目錄下的linuxrc,而這是一個指向/bin/busybox 的鏈接,也就是說,系統起來後運行的第一個程序就是busybox本身。
- linuxrc 會解析/etc/inittab內容,運行相關子進程,首先會運行etc/inittab配置文件裏面/etc/init.d/rcS這個腳本!
- rcS腳本中會運行mount -a命令,這條命令會讀取/etc/fstab 內容進行掛載各個文件系統,然後執行創建/dev文件的腳本。
- 系統起來後,登陸用戶後會運行/etc/profile,進行相關環境變量的配置;
剛剛拷貝過來的etc文件夾已經包含了上述的幾個必要文件,但是還需要做一些修改:
inittab:配置文件,裏面包含需要執行的腳本,第一個需要執行的腳本就是/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
rcS:腳本程序
首先設置網卡MAC地址和IP地址(也可以放到profile裏面),mount -a命令會掛載各個虛擬文件系統,mdev是udev的嵌入式簡化版本,udev/mdev是用來配合linux驅動工作的一個應用層的軟件,udev/mdev的工作就是配合linux驅動生成相應的/dev目錄下的設備文件,echo /sbin/mdev > /proc/sys/kernel/hotplug爲設置內核熱插拔,當有設備的熱插拔時調用/sbin/mdev。最後一條命令指定了一個主機名配置文件(這個文件一般文件名叫hostname或者HOSTNAME).
#! /bin/sh
ifconfig eth0 hw ether 02:00:92:B3:C4:08
ifconfig eth0 192.168.0.100
/bin/mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
/bin/hostname -F /etc/sysconfig/HOSTNAME
fstab:配置文件,在Linux開機以後自動配置哪些需要自動掛載的分區,mount -a指令會讀取本文件的內容,然後掛載虛擬文件系統。格式如下:
file system | mount point | type | options | dump | pass |
要掛載的特殊的設備 |
掛載點 | 文件系統類型,比如 ext2、ext3、proc、romfs、tmpfs 等等。 | 掛載選項,一般爲default | 爲 1 的話表示允許備份,爲 0 不備份,一般不備份,因此設置爲 0 | 磁盤檢查設置,爲 0 表示不檢查 |
#
# /etc/fstab: static file system information.
#
# file system mount type options dump pass
#/dev/root / ext2 rw,noauto 0 1
proc /proc proc defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
usbfs /proc/bus/usb usbfs defaults 0 0
/dev/fd0 /mnt/floppy auto noauto,owner 0 0
/dev/cdrom /mnt/cdrom iso9660 noauto,owner,ro 0 0
profile:PS1是主提示符變量,也是默認提示符變量。默認值[\u@\h \W]\$
,顯示用戶主機名稱工作目錄。
# /etc/profile: system-wide .profile file for the Bourne shells
export PS1='[\u@\h \W]\# '
接着在etc下創建目錄sysconfig, 然後再sysconfig目錄下創建HOSTNAME文件,往這個文件中寫入你想要設置的主機名。
這裏暫設主機名爲busybox。
實際上,到這裏根文件系統的主要目錄和文件已經構建完成,這時候的根文件系統已經可以運行!
9.構建其他目錄
爲了方便使用,我們再創建幾個其他常用目錄
- mkdir mnt tmp dev proc sys root
一個最小版根文件系統製作完成!下面就可以利用NFS或者寫入FLASH測試這個文件系統了。
10.添加root用戶
最後,給中這個文件系統添加一個root用戶,無密碼。
在/etc添加passwd文件,內容如下:
root::0:0:root:/root:/bin/sh
11.測試
我是直接將文件系統燒到板子的NAND FLASH裏面去測試的。
可以看到,文件系統已經成功啓動!接下來,寫個hello world 看下動態庫加載是否正常。
程序成功運行,動態庫加載也沒有什麼問題!