最小根文件系統所需元素:
(1) /dev/condsole
/dev/null
(2) init---->busybox
(3) /etc/inittab
(4) 配置文件裏指定的應用程序
(5) C庫(如果busybox中程序是動態使用鏈接庫的話)
先來配置編譯busybox
源文件busybox-1.7.0.tar.bz2
解壓
tar xjf busybox-1.7.0.tar.bz2
源碼目錄中的INSTALL文件詳細說明了如何編譯
make menuconfig # This creates a file called ".config"
make # This creates the "busybox" executable
make install # or make CONFIG_PREFIX=/path/from/root install
這裏的make install默認是安裝到pc上,而我們的目的是安裝到板子上,所以我們使用#號後面的方式
先執行make menuconfig編譯出配置菜單,但編譯出錯了
...
In file included from scripts/kconfig/lxdialog/checklist.c:24:0:
scripts/kconfig/lxdialog/dialog.h:31:20: fatal error: curses.h: 沒有那個文件或目錄
#include CURSES_LOC
^
compilation terminated.
make[2]: *** [scripts/kconfig/lxdialog/checklist.o] 錯誤 1
make[1]: *** [menuconfig] 錯誤 2
make: *** [menuconfig] 錯誤 2
這是因爲ubuntu系統中缺少一個套件 ncurses devel
sudo apt-get install libncurses5-dev
Preparing to unpack .../libtinfo-dev_5.9+20140118-1ubuntu1_i386.deb ...
Unpacking libtinfo-dev:i386 (5.9+20140118-1ubuntu1) ...
Selecting previously unselected package libncurses5-dev:i386.
Preparing to unpack .../libncurses5-dev_5.9+20140118-1ubuntu1_i386.deb ...
Unpacking libncurses5-dev:i386 (5.9+20140118-1ubuntu1) ...
正在設置 libtinfo-dev:i386 (5.9+20140118-1ubuntu1) ...
正在設置 libncurses5-dev:i386 (5.9+20140118-1ubuntu1) ...
裝完再make menuconfig
出來配置界面
[ ] Build BusyBox as a static binary (no shared libs)
如果選擇了這個靜態編譯,c庫就不需要另外加,但會大大增加文件大小,一般不選
除非我們的應用程序工具的運行要c庫,
而且,使用glibc時,靜態鏈接容易出問題,此時更加不要選擇靜態編譯
最新版的busybox可能可以配置設置交叉工具鏈,但1.7版本沒有這個選項,需要手動修改Makefile
一般linux裏這種選項是cross前綴的,修改後
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
或者在make時加上參數
make CROSS_COMPILE=arm-linux-
tab單詞補全
Busybox Settings --->
Busybox Library Tuning --->
Tab completion
mdev是自動創建設備節點
還有模塊相關命令
網絡
tar打包解壓命令
還有其他一些命令
最後make
安裝不要直接make install 這是裝到pc機上,而我們是要裝到板子上
make CONFIG_PREFIX=/home/book/work/workspace/firstfs install
這裏的"="號兩邊不要有空格
成功執行時出現以下打印信息
/home/book/work/workspace/firstfs/bin/addgroup -> busybox
/home/book/work/workspace/firstfs/bin/adduser -> busybox
/home/book/work/workspace/firstfs/bin/ash -> busybox
/home/book/work/workspace/firstfs/bin/cat -> busybox
...
進入firstfs目錄ll查看,有
bin linuxrc sbin usr
drwxrwxr-x 2 book book 4096 Nov 2 19:57 bin/
lrwxrwxrwx 1 book book 11 Nov 2 19:57 linuxrc -> bin/busybox*
drwxrwxr-x 2 book book 4096 Nov 2 19:57 sbin/
drwxrwxr-x 4 book book 4096 Nov 2 19:57 usr/
ll bin/cp
查看裏面的cp命令,是軟鏈接到busybox,硬鏈接數是1
lrwxrwxrwx 1 book book 7 Nov 2 19:57 bin/cp -> busybox*
好了busybox暫時搞定了
============================================================
然後是創建設備目錄
mkdir dev
cd dev
在dev目錄中創建2個字符設備,可以先查看完整linux系統中的相關文件屬性,再創建一樣的
sudo mknod console c 5 1
sudo mknod null c 1 3
再創建一個null字符設備
然後是inittab,我們只簡單的加一項
::askfirst:-/bin/sh
mkdir etc
vi inittab
加一句
console::askfirst:-/bin/sh
sh是一個程序,它的3標會定位到控制檯
如果不構造inittab的話,就會使個默認的配置項,
默認是
::ctrlaltdel:reboot
::shutdown:umount -a -r
::restart:init
::askfirst:-/bin/sh
:/dev/vc/2:askfirst:-/bin/sh
:/dev/vc/3:askfirst:-/bin/sh
:/dev/vc/4:askfirst:-/bin/sh
::sysinit:/etc/init.d/rcS
我們不需要這麼多
好了,由於我們做的是最小根文件系統,第四步的配置指定程序就不做了
第五步,c庫
在armgcc的lib目錄下
.a是靜態庫
.so是動態庫
當cp拷貝時加-d參數, 就拷貝so文件,而不是它的鏈接文件so.2
so比較小,具體啥區別暫不想它
mkdir lib
cp /home/book/soft/arm-linux-gcc-3.4.5/arm-linux/lib/*.so* lib/ -d
好了這樣最小根文件系統就做好了
bin dev etc lib linuxrc sbin usr
現在要燒到板子上,要先把最小根文件系統製作成yaffs2映像文件
yaffs1是小頁的512字節
yaffs2是大頁的2048字節
製作映像文件源碼在 yaffs_source_util_larger_small_page_nand.tar.bz2
可以支持大頁和小頁解壓後是Development_util_ok目錄
進入/Development_util_ok/yaffs2/utils 執行make
生成很多可執行文件,我們需要的是mkyaffs2image
sudo sudo cp mkyaffs2image /usr/local/bin/
sudo chmod +x /usr/local/bin/mkyaffs2image
cd ~/wrok/workspace
mkyaffs2image firstfs minifs.yaffs2
燒寫好啓動,輸出
Please press Enter to activate this console.
starting pid 763, tty '/dev/console': '/bin/sh'
說明我們在inittab配置文件中的腳本有作用
console::askfirst:-/bin/sh
先askfirst
按確定後啓動shell程序,並定向到控制檯console
============================================================
在shell,基本的ls,cd等命令就有了
但像ps命令就不能用
怎麼辦呢
linux有個proc虛擬文件系統,如果把它掛接到proc目錄,就可以使用ps命令查看內存中發生的一些事情
當前進程的信息會以文件的形式保存到proc目錄
新建proc目錄
再mount -t proc non /proc
就可以使用ps命令了
# ps
PID Uid VSZ Stat Command
1 0 3092 S init
2 0 SW< [kthreadd]
3 0 SWN [ksoftirqd/0]
4 0 SW< [watchdog/0]
5 0 SW< [events/0]
6 0 SW< [khelper]
55 0 SW< [kblockd/0]
56 0 SW< [ksuspend_usbd]
59 0 SW< [khubd]
61 0 SW< [kseriod]
73 0 SW [pdflush]
74 0 SW [pdflush]
75 0 SW< [kswapd0]
76 0 SW< [aio/0]
710 0 SW< [mtdblockd]
745 0 SW< [kmmcd]
763 0 3096 S -sh
778 0 3096 R ps
# ls -l /proc/1/fd
lrwx------ 1 0 0 64 Jan 1 00:21 0 -> /dev/console
lrwx------ 1 0 0 64 Jan 1 00:21 1 -> /dev/console
lrwx------ 1 0 0 64 Jan 1 00:21 2 -> /dev/console
============================================================
但是每次開機都手動mount太麻煩了
可以在inittab中加一條
::sysinit:/etc/init.d/rcS
不過最好加上這句,好處是當用nfs方式掛載,在關機時自動解掛,但如果是燒寫到flash的話即無所謂了
::shutdown:umount -a -r
然後創建rcS文件,加入一行腳本
mount -t proc non /proc
並加上可執行權限
sudo chmod +x /etc/init.d/rcS
除了使用mount -t proc non /proc命令
也可以用mount -a 作用是加載文件/etc/fstab中配置的所有設備
它會依賴一個配置文件/etc/fstab
它的格式是 (手冊第368頁)
#<file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
剛開始把defaults寫成default,竟然也有效果,後面才發現錯了,囧
好了
reboot看效果,也可以在製作根文件系統時直接做好燒寫
============================================================
現在dev下只有2個字符設備,如果大量增加設備的話,
手動創建太麻煩,可以用udev,自動創建dev設備節點
簡化版本是mdev
在mdev.txt中有使用說明,分6個步驟
Here's a typical code snippet from the init script:
[1] mount -t sysfs sysfs /sys
[2] echo /bin/mdev > /proc/sys/kernel/hotplug
[3] mdev -s
Of course, a more "full" setup would entail executing this before the previous
code snippet:
[4] mount -t tmpfs mdev /dev
[5] mkdir /dev/pts
[6] mount -t devpts devpts /dev/pts
按步就班:
掛載一個sysfs文件系統到/sys目錄,因爲使用mdev需要內核支持sysfs文件系統
tempfs文件系統可以減少對flash的讀寫
devpts虛擬終端用來支持對外部網絡telnet鏈接
先建個目錄,別忘了這步,不然啓動後進不去系統了
mkdir sys
修改etc/fstab來配置要掛載文件的系統
並且修改rcS加入要自動運行的命令
vi etc/fstab
添加
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
vi /etc/init.d/rcS
添加
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug #支持熱插拔,在熱插播時自動創建對應的設備節點
mdev -s #一開始就創建內核所支持的設備節點
============================================================
編譯製作jffs2映像文件的工具
即mtd-utils-05.07.23.tar.bz2
這個工具包裏有一個mkfs.jffs2工具, 它可以把我們準備好的文件系統的目錄製作成jffs2映像文件,燒寫到板子上
但是mkfs.jffs2工具依賴於一個壓縮解壓縮函數庫zlib
所以先配置編譯安裝 zlib庫,
tar xzf zlib-1.2.3.tar.gz
cd zlib-1.2.3/
配置, 參數prefix指定了安裝時的目錄
./configure --shared --prefix=/usr/
配置成功的話make
最後安裝sudo make install
然後編譯mkfs.jffs2
tar xzf mtd-utils-05.07.23.tar.bz2
cd mtd-utils-05.07.23/util
直接make生成mkfs.jffs2
然後安裝sudo make install
製作
mkfs.jffs2 -n -s 2048 -e 128KiB -d firstfs/ -o firstfs.jffs2
-s 一頁的大小,這個根據nand的實際參數
-e 可擦除塊的大小
-d 源目錄
-o 目標文件名
dnw燒寫並啓動
問題來了,從打印出來的啓動信息看到默認要掛接的是文件系統是yaffs
想要識別爲jffs2,可以在uboot控制檯修改啓動參數,來指定要掛接的文件系統類型
set bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 rootfstype=jffs2
save
jffs2的好處是可以壓縮映像,大大減小映像體積