1 獲取源碼解壓
從busybox的官方主頁http://www.busybox.net ,下載busybox的源碼,目前最新的版本為busybox-1.13.3.tar.bz2
#tar –jvxf busybox-1.13.3.tar.bz2
進入解壓后的busybox源碼目錄
#cd busybox-1.13.3
2 配置busybox
步驟跟編譯linux內(nèi)核時很像
#make menuconfig
出現(xiàn)一個圖形界面,選擇Busybox Settings,這里可以對編譯、安裝以及調(diào)試等模式進行配置。
然后選擇Build Options,對交叉編譯器以及編譯方式進行配置。
其中的第一項是Build Busybox as a static binary(no shared libs),如果選擇上,則busybox將以靜態(tài)形式進行編譯,否則將以動態(tài)方式編譯。此外,還需要對交叉編譯環(huán)境進行配置,選擇其中的Cross Compiler Perfix,輸入交叉編譯器的前綴,我們的嵌入式平臺上使用的是arm-uclinux-linux的交叉編譯工具。
這里我們先選擇靜態(tài)編譯,動態(tài)方式的稍后再講,注意Build with Large File Support (for accessing files > 2 GB)不要選(默認是選上的),否則編譯后會出現(xiàn)如下錯誤:
miscutils/lib.a(readahead.):In function ‘readahead_main’
readahead.(.text.readahead_main+0x70):undefined reference to ‘readahead’
collect2:ld returned 1 exit status
make :***[busybox_unstripped ]Error 1
3 編譯busybox
#make
4 安裝busybox
#make install
可以采用perfix參數(shù)安裝到指定目錄下,格式為:make install prefix=xxx目錄,如果不特別指定,將默認在busybox源碼目錄下生成一個_install目錄。到此,busybox基本上可以功成身退了。我們需要的就是busybox編譯出來的這個_install目錄。
進入_install目錄,可以看到一共有3個目錄和一個文件,分別是:bin、sbin和usr目錄以及l(fā)inuxrc文件。
在對這幾個目錄進行說明之前,先簡單介紹一下編譯生成的busybox可執(zhí)行文件,它存在于bin目錄下。Busybox使用了帶參的main函數(shù):int main(int argc,char *argv[]),在這個定義中,argc是傳遞進來的參數(shù)的個數(shù)(參數(shù)數(shù)量),而argv是一個字符串?dāng)?shù)組,代表從命令行傳遞進來的參數(shù)。argv的索引0是命令行調(diào)用的程序名??梢栽赽in目錄下進行如下操作:
#busybox pwd(注意,busybox這個可執(zhí)行文件不需要加./)
當(dāng)為一個可執(zhí)行程序創(chuàng)建符號鏈接后,在執(zhí)行這個符號鏈接時,就可以獲取到這個符號鏈接的名字。而busybox正是使用符號鏈接的方式使一個可執(zhí)行程序看起來像很多程序一樣。對于busybox中包含的每個工具來講,都會創(chuàng)建一個符號鏈接,這樣就可以使用這些符號鏈接來調(diào)用busybox了。然后busybox接著根據(jù)argv[0]的值來調(diào)用內(nèi)部工具。
下面分別對install目錄下的幾個文件進行一些說明。
Ø bin包含用戶工具,其中,busybox可執(zhí)行文件就在這個目錄下,該目錄下其他所有文件都是指向busybox的符號鏈接
Ø sbin目錄包含操作系統(tǒng)工具,同樣也指向busybox。
Ø linuxrc是一個鏈接文件,指向busybox。
5 添加etc目錄及基本配置文件
參考一個正常的linux系統(tǒng)將會發(fā)現(xiàn),此時busybox建立的文件系統(tǒng)還缺少很多文件。如果用這個作為文件系統(tǒng),將是無法運行的。生成這些配置可以選擇的方法有2種,一種是直接從一個正常運行的系統(tǒng)中拷貝,另一種是借助于 busybox的examples。顯然,選擇第二種會容易的多,我們直接拷貝examples/bootfloopy/etc到install目錄下。
#cp –a ../examples/bootfloppy/etc/ .
然后可以看看etc目錄下的文件,一共有3個目錄和文件,下面逐一對以上幾個文件進行分析和說明。
Ø inittab文件:系統(tǒng)啟動后訪問的第一個腳本文件,后續(xù)啟動的文件都由它指定。下面看一下busybox中原始的inittab文件內(nèi)容:
::sysint:/etc/init.d/rcS
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount –a -r
其中第一行指定系統(tǒng)的啟動腳本為/etc/init.d/rcS
第二行指定打開一個登錄會話
第三行指定在第三個虛擬終端打開一個無須登錄驗證的shell
第四行指定了當(dāng)按下ctrl+alt+del組合鍵時的執(zhí)行命令
Ø fstab文件:定義了文件系統(tǒng)的各個“掛載點”,需要與實際的系統(tǒng)相配合。默認的fstab文件內(nèi)容為:
proc /proc proc defaults 0 0
其他的根據(jù)需要再進行添加,比如devpts /dev/pts devpts defaults 0 0就是為UNIX PTYs準備的,后面講telnetd時要用到。
Ø profile文件:終端登陸之后首先運行的腳本。
6 添加dev目錄及基本設(shè)備文件
調(diào)試時要通過串口發(fā)送消息到終端顯示。因此串口控制臺和終端2個設(shè)備文件是必不可少的。
#mkdir dev
#mknod dev/console c 5 1
#mknod dev/ttyAMA0 c 204 64
在啟動參數(shù)中,設(shè)置console=ttyAMA0
7 添加其他常用目錄
可以選擇home、root、proc、mnt、lib、var、opt、tmp。
此時,一個基本的文件系統(tǒng)的功能就已經(jīng)完成了。可以采用NFS進行調(diào)試。但是,此時你可能會遇到如下問題,系統(tǒng)登錄后終端上會不斷打印:
cannot open /dev/ttyS2:No such file or directory.
原因出在/etc目錄下的inittab文件,我們看一下其內(nèi)容:
::sysint:/etc/init.d/rcS
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount –a -r
這條語句表示在第3個虛擬終端打開一個無須登錄驗證的shell。而我們之前沒有建立這個tty2設(shè)備,因此會出錯。解決的辦法有2個:一是屏蔽該語句,二是建立該設(shè)備節(jié)點。我們選擇將其屏蔽。
8 相關(guān)問題
8.1 使用動態(tài)方式編譯busybox
進入Build Options時,不要選擇Build Busybox as a static binary,其他所有操作步驟跟靜態(tài)編譯一樣,你會發(fā)現(xiàn)這樣建立的文件系統(tǒng)無法啟動,終端上打印出如下消息:
Kernel panic-not synving:No init found. Try passing init=option to kernel.
為什么會出現(xiàn)這種問題呢?這就得回到兩種編譯方式的特點上來。靜態(tài)編譯時是將所用到的庫文件一起編譯了進去,而動態(tài)編譯時是在需要時才調(diào)用相應(yīng)的庫。我們選擇動態(tài)編譯后,沒有添加任何庫文件就運行,顯然是會出錯的。那么如何查看 busybox可執(zhí)行文件里使用的庫呢。Readelf這個工具提供了解決辦法。使用如下命令,參數(shù)d表示將文件中所有的動態(tài)部分予以顯示。
# arm-uclibc-linux-readelf -d busybox
Dynamic section at offset 0xca014 contains 18 entries:
標記 類型 名稱/值
0x00000001 (NEEDED) 共享庫:[libm.so.0]
0x00000001 (NEEDED) 共享庫:[libc.so.0]
0x0000000c (INIT) 0xbe24
0x0000000d (FINI) 0xb2054
0x00000004 (HASH) 0x80e8
0x00000005 (STRTAB) 0xa500
0x00000006 (SYMTAB) 0x8b70
0x0000000a (STRSZ) 3259 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0xda0cc
0x00000002 (PLTRELSZ) 3040 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0xb244
0x00000011 (REL) 0xb1bc
0x00000012 (RELSZ) 136 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000000 (NULL) 0x0
從上面的結(jié)果中,我們可以看到,busybox這個程序使用到了libm.so.0和 libc.so.0兩個庫文件,實際上這是2個符號鏈接,分別指向libc-0.9.28.so和libuClibc-0.9.28.so。將以上四個文件分別拷貝到lib目錄下。按理說,這樣應(yīng)該就可以了,但是仍然無法正常運行。顯示的錯誤信息和剛剛沒加庫之前一樣??赡艿脑蛴?種:一是庫文件沒有添加全,二是庫文件沒有正確被加載。根據(jù)readelf顯示的結(jié)果應(yīng)該不是第一種原因。那么到底為什么沒被正確加載呢?原來庫文件的加載,還需要一個共享庫加載器。找到對應(yīng)的文件ld-uClibc-0.9.28.so和ld-uClibc.so.0添加到lib目錄下后。運行正常。
8.2 終端登錄用戶驗證功能添加
需要在etc目錄下增加passwd、group和shadow(在編譯busybox時如果不選擇shadow功能將不需要這個文件)3個文件。
生成這3個文件的方法有:
Ø 手動生成,按照格式規(guī)范自己編寫內(nèi)容;
Ø 通過busybox提供的工具adderuser自動生成
8.2.1 手動方式
首先我們介紹一下如何手動添加。以增加root用戶為例,增加passwd文件,其內(nèi)容為:
#cat passwd
root:x:0:0:root:/root:/bin/sh
同時,此時要確定root目錄已經(jīng)存在。
passwd一共由7個字段組成,6個冒號將其隔開。它們的含義分別為:
1 用戶名
2 是否有加密口令,x表示有,不填表示無,采用MD5、DES加密。
3 用戶ID
4 組ID
5 注釋字段
6 登錄目錄
7 所使用的shell程序
增加group文件,其內(nèi)容為:
#cat group
root:x:0:
Group一共由4個字段組成,3個冒號將其隔開,它們的含義分別為:
1 組名
2 是否有加密口令,同passwd
3 組ID
4 指向各用戶名指針的數(shù)組
由于busybox默認啟動了shadow模式,因此需要增加shadow文件,其內(nèi)容為:
#cat shadow
root:$1$3jZ93Mwq$oaeef6lWIuThavs8wD0Wh1:0:0:99999:7:::
shadow一共由9個字段組成,8個冒號將其隔開,它們的含義分別為:
1 用戶名
2 加密后的口令,若為空,表示該用戶不需要口令即可登陸,若為*號,表示該賬號被禁用。 上面的表示的是123456加密后的口令。
3 從1970年1月1日至口令最近一次被修改的天數(shù)
4 口令在多少天內(nèi)不能被用戶修改
5 口令在多少天后必須被修改(0為沒有修改過)
6 口令過期多少天后用戶賬號被禁止
7 口令在到期多少天內(nèi)給用戶發(fā)出警告
8 口令自1970年1月1日被禁止的天數(shù)
9 保留域
這里強調(diào)一下shadow文件的由來。/etc/passwd文件對系統(tǒng)的所有用戶都是可讀的,這樣的好處是每個用戶都知道系統(tǒng)上有哪些用戶,但缺點是其他用戶的口令容易受到攻擊,尤其是當(dāng)口令較簡單時。所以一些linux系統(tǒng)中使用到了影子口令文件shadow,將用戶的口令存儲在另一個文件/etc/shadow中,該文件只有根用戶root可讀,大大提高了安全性。
不過,采用這種手動添加文件的方法有一個缺陷,就是如果要為用戶設(shè)置登陸口令的話,shadow文件中必須填寫加密后的口令,而這個加密算法我們又不知道,即使知道,要經(jīng)過轉(zhuǎn)換后再添加,比較麻煩。此時,不妨試一下第二種方法。
8.2.2 自動方式
自動生成是使用了busybox提供的adduser工具和passwd工具。
在文件系統(tǒng)正常運行起來后,使用adduser命令,使用方法為:
#adduser root
然后就會在etc目錄下自動生成passwd 、group和shadow3個文件。但是運行該命令后會打印出如下消息:
passwd:unknown uid 0
這表示不能為該用戶設(shè)置密碼,此時你會發(fā)現(xiàn)要passwd命令也無法使用。
解決的辦法是,打開passwd文件,其內(nèi)容為:
root:x:1000:1000:Linux User…:/home/root:/bin/sh
將用戶ID和組ID均更改為0
打開group文件,其內(nèi)容為:
root:x:1000:
同樣將組ID改為0
然后,passwd命令就可以正常使用了。這時為root用戶設(shè)置口令:
#passwd root
根據(jù)提示輸入密碼。其中,root用戶登陸后的目錄可以手動進行更改。
8.3 telnetd功能添加
busybox默認已經(jīng)添加了對telnetd和telnet功能的支持,只需要完成一些相關(guān)的設(shè)置工作就可以啟動這2個功能了。
Ø 創(chuàng)建/dev/pts目錄
Ø 在/etc/fstab中添加如下信息,掛載devpts文件系統(tǒng)
devpts /dev/pts devpts defaults 0 0
Ø 在/dev目錄下增加ptmx設(shè)備文件:
#mknod ptmx c 5 2
Ø 在rcS文件中添加如下腳本,啟動telnetd
if [ -x /usr/sbin/telnetd ] ;
then
telnetd&
fi
Ø 在/dev目錄下增加null設(shè)備文件,否則上述腳本運行時會出錯:提示找不到null文件。
#mknod null c 1 3
此時,telnetd功能開機就可以啟動了。
2 遇到的一些問題:
(1)加載根文件系統(tǒng)時出現(xiàn):
?。苧ee memory :112K
request_module: runaway loop modprobe binfmt-464c
request_module: runaway loop modprobe binfmt-464c
request_module: runaway loop modprobe binfmt-464c
request_module: runaway loop modprobe binfmt-464c
request_module: runaway loop modprobe binfmt-464c
.......
此問題困擾了我2天,媽媽的,讓我心情大為不爽。不過最終還是解決了,只要不放棄,問題是總能解決的,關(guān)鍵是時間問題啊。出現(xiàn)此現(xiàn)象的原因在于系統(tǒng)無法執(zhí)行l(wèi)inuxrc。問題出在busybox,由于我的linuxrc的首句是#!/bin/sh,也就是由sh來解析該腳本文件,但是我的 busybox生成的bin文件下根本沒有sh命令,當(dāng)然無法執(zhí)行。解決方法是重新配置busybox,在shell---->Choose your default shell(ash)---->下選中ash,然后make,最后在make加上ARCH=arm和CROSS_COMPILE=arm- linux-(建議使用絕對路徑,我一直這么用),即使在Makefile中已經(jīng)指定了ARCH和CROSS_COMPILE,這是網(wǎng)上一位同仁給的建議,否則有可能遇到一些問題,比如我這次遇到的request_module: runaway loop modprobe binfmt-464c
注: 本人在做的 過程也出現(xiàn)這個問題,原因不是上邊提到過 的,而是 etc中幾個關(guān)鍵文件不正確 ,此問題可能還有別 的原因 有待發(fā)現(xiàn)
(2)加載根文件系統(tǒng)時出現(xiàn):
Warning:unable to open initial console
解決辦法:
cd /dev
mknod console c 5 1
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。