系統開機少不了 init,command 當然也不能少,若要從系統上抽取某些 command 來用,不單單只是複製一個執行檔那麼簡單,對應的函式庫也要一起包含起來才有辦法。來個小實驗吧,我習慣使用 bash 當成我的操作環境,我要把 bash 加到我的 embedded 目錄 /root/images/main (以下簡稱環境)裡。

再簡單也不過的一個做法,先來把 bash 複製到環境內的 /bin
# cp -a `which bash` /root/images/main/bin

我們把 /root/images/main/bin 當成家目錄來執行 bash 試試看吧
# chroot /root/images/main/ bash
bash: error while loading shared libraries: libtermcap.so.2: cannot open shared object file: No such file or directory

看到錯誤囉,看來這一切不是 portable 那般簡單;錯誤的訊息提示的很明確,就是缺少 libraries,這點大家不會懷疑吧,那麼要怎麼知道 bash 需要哪些 libraries 呢?一個很少用的命令有機會使用囉。
# ldd `which bash`
        linux-gate.so.1 =>  (0x008c2000)
        libtermcap.so.2 => /lib/libtermcap.so.2 (0x435ca000)
        libdl.so.2 => /lib/libdl.so.2 (0x43582000)
        libc.so.6 => /lib/libc.so.6 (0x43443000)
        /lib/ld-linux.so.2 (0x43421000)

看來好像需要很多東西的樣子,我們要這些 libraries 通通複製到環境內的,先來看看 libraries 的狀態。
# ls -l /lib/libtermcap.so.2 /lib/libdl.so.2 /lib/libc.so.6 /lib/ld-linux.so.2
lrwxrwxrwx 1 root root  9 10月 29 04:34 /lib/ld-linux.so.2 -> ld-2.5.so
lrwxrwxrwx 1 root root 11 10月 29 04:34 /lib/libc.so.6 -> libc-2.5.so
lrwxrwxrwx 1 root root 12 10月 29 04:34 /lib/libdl.so.2 -> libdl-2.5.so
lrwxrwxrwx 1 root root 19 10月 29 04:35 /lib/libtermcap.so.2 -> libtermcap.so.2.0.8

全部都是 softlink 啊,我習慣是依樣畫葫蘆的複製過去,雖然說直接 cp 也是可以,當然我也有已經寫好的 shell script。
# ls -l /root/images/main/lib/libtermcap.so.2 /root/images/main/lib/libdl.so.2 /root/images/main/lib/libc.so.6 /root/images/main/lib/ld-linux.so.2
lrwxrwxrwx 1 root root  9 10月 31 10:06 /root/images/main/lib/ld-linux.so.2 -> ld-2.5.so
lrwxrwxrwx 1 root root 11 10月 31 10:06 /root/images/main/lib/libc.so.6 -> libc-2.5.so
lrwxrwxrwx 1 root root 12 10月 31 10:06 /root/images/main/lib/libdl.so.2 -> libdl-2.5.so
lrwxrwxrwx 1 root root 19 10月 31 10:06 /root/images/main/lib/libtermcap.so.2 -> libtermcap.so.2.0.8

再一次把環境當成根目錄來執行 bash 試試看吧^^
# chroot /root/images/main/ bash
bash-3.1#

哈哈~bash 出現囉,版本3.1也被大家發現哩~基本上複製一個 command 大致完成哩,但是還是得提醒大家雖然這樣測試正常,但是不保證開機也會正常唷,所以另一個不常用的指令也要上場了。我要把 ldconfig(not a dynamic executable) 複製到環境的 /sbin 內,複製完成過後來檢測一下!
# chroot /root/images/main/ ldconfig -v
ldconfig: Can't open configuration file /etc/ld.so.conf: No such file or directory
ldconfig: Can't stat /usr/lib: No such file or directory
/lib:
        libtermcap.so.2 -> libtermcap.so.2.0.8
        ld-linux.so.2 -> ld-2.5.so
        libc.so.6 -> libc-2.5.so
        libdl.so.2 -> libdl-2.5.so

看到哩錯誤就來修正吧~
# touch /root/images/main/etc/ld.so.conf
# mkdir /root/images/main/usr/lib

完成修正後再次檢測就正常囉!

我常使用的指令還真是不少啊,若是一個一個這樣做就麻煩大哩,因為 linux 實在是很 friendly,command 常常可以下個 -h 或是 --help,而且會有非常多的參數可以選擇,但是要最小化系統,甚至到一個 embedded 的環境那些都是不必要的,因此得把 busybox 請出來囉!!
下載了 busybox 之後解壓縮,進到該目錄,這一切的步驟就和編譯核心差不多,而且內容比編譯核心好看許多,其實大多都只是勾選自己需要的指令而已。
# cd /root/src/busybox-1.7.2
# make menuconfig

比較需要注意的是 Busybox Setting ---> General Configuration ---> Path to BusyBox executable 這裡要把路徑指定到環境 /root/images/main 內,之後當然也就是 make ; make install,完成之後到環境內的 bin 和 sbin 看看吧,我所需要的100個指令都是 softlink 到環境內的 /bin/busybox,那 busybox 這個檔案有多大呢?
# ls -lh /root/images/main/bin/busybox
-rwxr-xr-x 1 root root 437K 10月 29 08:17 /root/images/main/bin/busybox

的確沒有看錯啦,100個指令只需要437K,而且包含 init 在內,但是要記得 ldd 看一下 busybox 需要哪些 libraries 唷,一樣都要把 libraries 複製到環境內,這時候可以再 chroot 到環境內試試看是否正常運作囉^^

下一步驟我希望可以帶大家完成開機的步驟^^,今天解說的一切看得懂就懂吧...基本上是以備忘之名來發表文章的=.=,因為寫教學壓力就太沉重哩,本人沒有那麼厲害啦。
更多資訊請參考:
最新超值旗艦機開箱
比螺旋燈泡還省電的迷你 NAS
26800mAh筆電行動電源