- 論壇徽章:
- 0
|
《我也來學(xué)做嵌入式Linux系統(tǒng)V0.1》
作者:九賤
E-mail:kendo999@sohu.com
個人站點(diǎn):www.skynet.org.cn
第一章 前言
目的
本文的目的,是講述嵌入式Linux系統(tǒng)的建立、開發(fā)的一般過程。制作一個小型的Linux的系統(tǒng),可以移植至其它硬盤、軟盤、優(yōu)盤、flash rom……
關(guān)于作者
九賤,E名kendo,喜歡網(wǎng)絡(luò)入侵技術(shù)、防火墻、入侵檢測技術(shù)及網(wǎng)絡(luò)技術(shù),對Linux也頗感興趣,想認(rèn)識有共同愛好的朋友。最近閑暇,把一些學(xué)過的東西寫下來,總結(jié)總結(jié),以作備忘這需。已完成的有《網(wǎng)絡(luò)入侵檢測設(shè)計(jì)與Snort2.2源碼分析》和這篇《我也來學(xué)做嵌入式Linux》。正在進(jìn)行中的有《Windows防火墻技術(shù)實(shí)現(xiàn)大全》和《Linux防火墻實(shí)現(xiàn)及源碼分析》。大家可以在CU上,或者是到我的小站www.skynet.org.cn上與我交流
做一個嵌入式Linux系統(tǒng)究竟要做哪些工作
做一個嵌入式Linux系統(tǒng)究竟需要做哪些工作?也就是本文究竟要講述哪些內(nèi)容?我先介紹一個脈絡(luò),可以做為我們后面工作的一個總的提綱:
第一步、建立交叉編譯環(huán)境
沒有交叉開發(fā)經(jīng)驗(yàn)的讀者,可能一時很難接受這個概念。首先,要明白兩個概念:一般我們工作的機(jī)器,稱為開發(fā)機(jī)、主機(jī);我們制作好的系統(tǒng)將要放到某臺機(jī)器,如手機(jī)或另一臺PC機(jī),這臺機(jī)我們稱為目標(biāo)主機(jī)。
我們一般開發(fā)機(jī)上已經(jīng)有一套開發(fā)工具,我們稱之為原生開發(fā)套件,我們一般就是用它們來寫程序,那么,那什么又是交叉編譯環(huán)境呢?其實(shí)一點(diǎn)也不神秘,也就是在開發(fā)機(jī)上再安裝一套開發(fā)工具,這套開發(fā)工具編譯出來的程序,如內(nèi)核、系統(tǒng)工作或者我們自己的程序,是放在目標(biāo)主機(jī)上運(yùn)行的。
那么或許有初學(xué)者會問,直接用原生開發(fā)工具為目標(biāo)主機(jī)編譯程序不就完了?至少我當(dāng)初是這么想的。一般來說,我們的開發(fā)機(jī)都是X86平臺,原生開發(fā)套件開發(fā)的工具,也針對X86平臺,而我們的目標(biāo)主機(jī)可能是PowerPC、IXP、MIPS……所以,我們的交叉編譯環(huán)境是針對某一類具體平臺的。
一般來講,交叉開發(fā)環(huán)境需要二進(jìn)制工具程序、編譯器、C鏈接庫,嵌入式開發(fā)常用的這三類軟件是:
Binutils
Gcc
uClibc
當(dāng)然,GNU包含的工具套件不僅于此,你還要以根據(jù)實(shí)際需要,進(jìn)行選擇
第二步、編譯內(nèi)核
開發(fā)工具是針對某一類硬件平臺,內(nèi)核同樣也是。這一步,我們需要用第一步中建立的工具,對內(nèi)核進(jìn)行編譯,對于有內(nèi)核編譯經(jīng)驗(yàn)的人來說,這是非常簡單的;
第三步、建立根文件系統(tǒng)
也就是建立我們平常看到的bin、dev、proc……這一大堆目錄,以及一些必備的文件;另外,我們還需要為我們的目標(biāo)系統(tǒng)安裝一些常用的工具軟件,如 ls、ifconfig……當(dāng)然,一個辦法是找到這些工具的源代碼,用第一步建立的交叉編譯工具來編譯,但是這些軟件一是數(shù)量多,二是某些體積較大,不適合嵌入式系統(tǒng),這一步,我們一般都是用busybox來完成的,包括系統(tǒng)引導(dǎo)軟件init;
最后,我們?yōu)橄到y(tǒng)還需要建立初始化的引導(dǎo)文件,如inittab……
第四步、啟動系統(tǒng)
在這一步,我們把建立好的目標(biāo)、文件、程序、內(nèi)核及模塊全部拷貝到目標(biāo)機(jī)存儲器上,如硬盤。然后為系統(tǒng)安裝bootloader,對于嵌入式系統(tǒng),有許多引導(dǎo)程序可供我們使用。不過它們許多都有硬件平臺的限制。當(dāng)然,如果你是工作在X86,可以直接用lilo來引導(dǎo),事實(shí)上,本文就是采用的lilo。
做到這一步,將目標(biāo)存儲設(shè)備掛上目標(biāo)機(jī),如果順利,就可以啟動系統(tǒng)了。
當(dāng)然,針對某些特別的平臺,不能像硬盤這樣拷貝了,需要讀卡器、燒錄……但是基本的方法是相通的!
第五步、優(yōu)化和個性化系統(tǒng)
通過前四步,我們已經(jīng)得到了一個可以正常工作的系統(tǒng)。在這一步里,就是發(fā)揮你想像的時候了……
本文的工作環(huán)境
項(xiàng)目根目錄/home/kendo/project ------>;我將它指定至PATH:$PRJROOT
子目錄及說明
目錄 內(nèi)容
bootloader 目標(biāo)板的引導(dǎo)加載程序,如lilo等
build-tools 建立交叉編譯平臺的工具源碼
debug 調(diào)試工具及所有相關(guān)包
doc 項(xiàng)目中用到的所有文檔
images 編譯好的內(nèi)核映像,以及根文件系統(tǒng)
kernel 各個版本的Linux內(nèi)核源碼
rootfs 制作好的根文件系統(tǒng)
sysapps 目標(biāo)板將要用到的系統(tǒng)應(yīng)用系統(tǒng),比如thttpd,udhcpd等
tmp 存放臨時文件
tools 編譯好的跨平臺開發(fā)工具鏈以及C鏈接庫
工作的腳本
#!/usr/bin
export PROJECT=skynet
export PRJROOT=/home/${PROJECT}
export TARGET=i386-linux
export PREFIX=${PRJROOT}/tools
export TARGET_PREFIX=${PREFIX}/${TARGET}
export PATH=${PREFIX}/bin:/bin:/sbin:/usr/bin:/usr/sbin
cd $PRJROOT
第二章 建立交叉編譯環(huán)境
在CU中發(fā)表的另一篇同名的貼子里,我講述了一個全手工創(chuàng)建交叉編譯環(huán)境的方法。目前,創(chuàng)建交叉編譯環(huán)境,包括建立根文件,一般來講,有兩種方法:
手功創(chuàng)建
可以得到最大程序的個性化定制,缺點(diǎn)是過程繁雜,特別是極易出錯,注意這個“極”字,包括有經(jīng)驗(yàn)的開發(fā)人員;
自動創(chuàng)建
無它,方便而。
因?yàn)榍耙黄恼轮,已?jīng)講述了全手工創(chuàng)建交叉編譯環(huán)境的一般性方法,本文就不打算再重復(fù)這個步驟了,感興趣的朋友,可以再去搜索那篇貼子,提醒一點(diǎn)的就是,在準(zhǔn)備工具鏈的時候,要注意各個工具版本之間的搭配、每個工具需要哪些補(bǔ)丁,我建議你在google上針對這兩項(xiàng)搜索一下,準(zhǔn)備一個清單,否則……
本章要講述的是自動創(chuàng)建交叉編譯環(huán)境的方法。目標(biāo),針對商業(yè)硬件平臺,廠家都會為你提供一個開發(fā)包,我用過XX廠家的IXP425和MIPS的,非常地方便,記得我第一次接觸嵌入式開發(fā),拿著這個開發(fā)包自動化創(chuàng)建交叉編譯環(huán)境、編譯內(nèi)核、建立根文件系統(tǒng)、創(chuàng)建Ram Disk,我反復(fù)做了三四次,結(jié)果還不知道自己究竟做了些什么,呵呵,夠傻吧……
所以,建議沒有這方面經(jīng)驗(yàn)的讀者,還是首先嘗試一下手工創(chuàng)建的方法吧,而本章接下來的內(nèi)容,是送給曾經(jīng)被它深深傷害而不想再次去親歷這項(xiàng)工作而又想提高交率而又在通用平臺上工作沒有商業(yè)開發(fā)包的朋友。
建立交叉開發(fā)工具鏈
準(zhǔn)備工具:
buildroot-0.9.27.tar.tar
只需要一個軟件?對,其它的不用準(zhǔn)備了,buildroot事實(shí)上是一個腳本與補(bǔ)丁的集合,其它需要用到的軟件,如gcc、uClibc,你只需在buildroot中指明相應(yīng)的版本,它會自動去給你下載。
事實(shí)上,buildroot到網(wǎng)上去下載所需的所有工作是需要時間的,除非你的帶寬足夠,否則下載軟件時間或許會占去80%,而我在做這項(xiàng)工作之間,所需的工作鏈全部都在我本地硬盤上,我解壓開buildroot后,新建dl文件夾,將所有工具源碼的壓縮包拷貝進(jìn)去,呵呵,buildroot就不用去網(wǎng)上下載了。
我的軟件清單:
Linux-libc-headers-2.4.27.tar.bz2
Gcc-3.3.4.tar.bz2
binutils 2.15.91.0.2.tar.bz2
uClibc 0.9.27.tar.bz2
genext2fs_1.3.orig.tar.gz
ccache-2.3.tar.gz
將它拷貝到${PRJROOT}/build-tools下,解壓
[root@skynet build-tools]# tar jxvf buildroot-0.9.27.tar.tar
[root@skynet build-tools]#cd buildroot
配置它:
[root@skynet build-tools]#make menuconfig
Target Architecture (i386) --->; 選擇硬件平臺,我的是i386
Build options --->; 編譯選項(xiàng)
這個選項(xiàng)下重要的是(${PRJROOT}/tools) Toolchain and header file location?編譯好的工具鏈放在哪兒?
如果你像我一樣,所有工具包都在本地,不需它到網(wǎng)上自動下載,可以把wget command選項(xiàng)清空;
Toolchain Options --->; 工具鏈選項(xiàng)
--- Kernel Header Options 頭文件它會自動去下載,不過應(yīng)該保證與你將要用的內(nèi)核是同一個版本;
[] Use the daily snapshot of uClibc? 使用最近的uClibc的snapshot
Binutils Version (binutils 2.15.91.0.2) --->; Binutils的版本
GCC compiler Version (gcc 3.4.2) --->; gcc 版本
# Build/install c++ compiler and libstdc++?
[ ] Build/install java compiler and libgcj? 支持的語言,我沒有選擇java
[ ] Enable ccache support? 啟用ccache的支持,它用于編譯時頭文件的緩存處理,用它來編譯程序,第一次會有點(diǎn)慢,但是以后的速度可就很理想了,呵呵……
--- Gdb Options 根據(jù)你的需要,選擇gdb的支持
Package Selection for the target --->;
這一項(xiàng)我沒有選擇任意一項(xiàng),因?yàn)槲掖蛩愀募到y(tǒng)及busybox 等工具鏈創(chuàng)建成工,手工來做。
Target Options --->; 文件系統(tǒng)類型,根據(jù)實(shí)際需要選,我用的ext2;
配置完成后,編譯它:
[root@skynet build-tools]#make
這一項(xiàng)工作是非;〞r間的,我的工具包全部在本地,也花去我一小時十三分的時間,如果全要下載,我估計(jì)網(wǎng)速正常也要多花一兩個鐘頭。
經(jīng)過漫長的等待(事實(shí)上并不漫長,去打了幾把游戲,很快過去了):
……
make[1]: Leaving directory `/home/skynet/build-tools/buildroot/build_i386/genext2fs-1.3'
touch -c /home/skynet/build-tools/buildroot/build_i386/genext2fs-1.3/genext2fs
#-@find /home/skynet/build-tools/buildroot/build_i386/root/lib -type f -name \*.so\* | xargs /home/skynet/tools/bin/i386-linux-uclibc-strip --remove-section=.comment --remove-section=.note --strip-unneeded 2>;/dev/null || true;
/home/skynet/build-tools/buildroot/build_i386/genext2fs-1.3/genext2fs -i 503 -b 1056 \
-d /home/skynet/build-tools/buildroot/build_i386/root -q -D target/default/device_table.txt /home/skynet/build-tools/buildroot/root_fs_i386.ext2
大功告成。!
清點(diǎn)戰(zhàn)利品
讓我來看看它究竟做了哪些事情吧:
[root@skynet skynet]# cd tools
[root@skynet tools]# ls
bin bin-ccache i386-linux i386-linux-uclibc include info lib libexec man usr
bin:所有的編譯工具,如gcc,都在這兒了,只是加了些指定的前綴;
bin-ccache:如果在Toolchain optaion中沒有選擇對ccache的支持,就沒有這一項(xiàng)了;
i386-linux:鏈接文件;實(shí)際指向include
i386-linux-uclibc:uclibc的相關(guān)工具;
include:供交叉開發(fā)工具使用的頭文件;
info:gcc 的info文件;
lib:供交叉開發(fā)工具使用的鏈接庫文件;
……
現(xiàn)在可以把編譯工具所在目錄XXX/bin添加至PATH了
測試工具鏈
如果你現(xiàn)在寫一個程序,用i386-linux-gcc來編譯,運(yùn)行的程序會告訴你:
./test: linked against GNU libc
因?yàn)槌绦蜻\(yùn)行庫會尋到默認(rèn)的/lib:/usr/lib上面去,而我們目前的uclibc的庫并不在那里(雖然對于目標(biāo)機(jī)來講,這是沒有錯的),所以,也只能暫時靜態(tài)編譯,試試它能否工作了。當(dāng)然,你也可以在建好根文件系統(tǒng)后,試試用chroot……
第三章 編譯內(nèi)核
本章的工作,是為目標(biāo)機(jī)建立一個合適的內(nèi)核,對于建立內(nèi)核,我想有兩點(diǎn)值得考慮的:
1、功能上的選擇,應(yīng)該能夠滿足需要的情況下,盡量地小;
2、小不是最終目的,穩(wěn)定才是;
所以,最好編譯內(nèi)核前有一份目標(biāo)機(jī)硬件平臺清單以及所需功能清單,這樣,才能更合理地裁減內(nèi)核。
準(zhǔn)備工具
Linux內(nèi)核源碼,我選用的是Linux-2.4.27.tar.bz2
編譯內(nèi)核
將Linux-2.4.27.tar.bz2拷貝至${PRJROOT}/kernel,解壓
#cd linux-2.4.27
//配置
# make ARCH=i386 CROSS_COMPILE=i386-linux- menuconfig
//建立源碼的依存關(guān)系
# make ARCH=i386 CROSS_COMPILE=i386-linux- clean dep
//建立內(nèi)核映像
# make ARCH=i386 CROSS_COMPILE=i386-linux- bzImage
ARCH指明了硬件平臺,CROSS_COMPILE指明了這是交叉編譯,且編譯器的名稱為i386-linux-XXX,這里沒有為編譯器指明路徑,是因?yàn)槲仪懊嬉褜⑵浼尤胫镰h(huán)境變量PATH。
又是一個漫長的等待……
OK,編譯完成,673K,稍微大了點(diǎn),要移到其它平臺,或許得想辦法做到512以下才好,回頭來想辦法做這個工作。
安裝內(nèi)核
內(nèi)核編譯好后,將內(nèi)核及配置文件拷貝至${PRJROOT}/images下。
# cp arch/i386/boot/bzImage ${PRJROOT}/images/bzImage-2.4.27-rmk5
# cp vmlinux ${PRJROOT}/images/vmlinux-2.4.27-rmk5
# cp System.map ${PRJROOT}/images/System-2.4.27-rmk5
# cp .config ${PRJROOT}/images/2.4.27-rmk5
我采用了后綴名的方式重命名,以便管理多個不同版本的內(nèi)核,當(dāng)然,你也可以不用這樣,單獨(dú)為每個版本的內(nèi)核在images下新建對應(yīng)文件夾也是可行的。
安裝內(nèi)核模塊
完整內(nèi)核的編譯后,剩下的工作就是建立及安裝模塊了,因?yàn)槲业膬?nèi)核并沒有選擇模塊的支持(這樣擴(kuò)展性差了一點(diǎn),但是對于我的系統(tǒng)來說,功能基本上定死了,這樣影響也不太大),所以,剩下的步驟也省去了,如果你還需要模塊的支持,應(yīng)該:
//建立模塊
#make ARCH=i386 CROSS_COMPILE=i386-linux- modules
//安裝內(nèi)核模塊至${PRJROOT}/images
#make ARCH=i386 CROSS_COMPILE= i386-linux- \
>;INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.4.18-rmk5 \
>;modules_install
最后一步是為模塊建立依存關(guān)系,不能使用原生的depmod來建立,而需要使用交叉編譯工具。需要用到busybox中的depmod.pl腳本,很可惜,我在busybox1.0.0中,并沒有找到這個腳本,所以,還是借用了busybox0.63中scripts中的depmod.pl。
將depmod.pl拷貝至${PREFIX}/bin目錄中,也就是交叉編譯工具鏈的bin目錄。
#depmod.pl \
>;-k ./vmlinux –F ./System.map \
>;-b ${PRJROOT}/images/modules-2.4.27-rmk5/lib/modules >; \
>;${PRJROOT}/images/modules-2.4.27-rmk5/lib/modules/2.4.27-rmk5/modules.dep
注:后面討論移植內(nèi)核和模塊內(nèi)容時,我只會提到內(nèi)核的拷貝,因?yàn)槲业南到y(tǒng)并沒有模塊的支持。如果你需要使用模塊,只需按相同方法將其拷貝至相應(yīng)目錄即可。
附,內(nèi)核編譯清單
附,內(nèi)核選擇:
內(nèi)核編譯記錄:
Code maturity level options 不選
Loadable module support 不選
Processor type and features 根據(jù)實(shí)際,選擇處理器類型
General setup --->;
# Networking support
# PCI support
(Any) PCI access mode
# PCI device name database
# System V IPC
# Sysctl support
(ELF) Kernel core (/proc/kcore) format
# Kernel support for ELF binaries
# Power Management support
Memory Technology Devices (MTD) --->; MTD設(shè)備,我用CF卡,不選
Parallel port support --->; 不選
Plug and Play configuration --->; 我的系統(tǒng)用不著即插即用,不選
Block devices --->;
# Loopback device support
# RAM disk support
(4096) Default RAM disk size (NEW)
# Initial RAM disk (initrd) support
Multi-device support (RAID and LVM) --->; 不選
Networking options --->; 基本上都選了
ATA/IDE/MFM/RLL support --->; 用了默認(rèn)的
Telephony Support --->; 不選
SCSI support --->; 不選
Fusion MPT device support --->; 不選
I2O device support --->; 不選
Network device support --->; 根據(jù)實(shí)際情況選擇
Amateur Radio support --->; 不選
IrDA (infrared) support --->; 不選
ISDN subsystem --->; 不選
Old CD-ROM drivers (not SCSI, not IDE) --->; 不選
Input core support --->; 不選
Character devices --->;
# Virtual terminal
# Support for console on virtual terminal
# Standard/generic (8250/16550 and compatible UARTs) serial support
# Support for console on serial port
Multimedia devices --->; 不選
File systems --->;
# Kernel automounter version 4 support (also supports v3)
# Virtual memory file system support (former shm fs)
# /proc file system support
# Second extended fs support
Console drivers --->;
# VGA text console 調(diào)試時接顯示器用
剩下三個都不要
Sound --->;
USB support --->;
Kernel hacking --->;
第四章 建立根文件系統(tǒng)
1、建立目錄
構(gòu)建工作空間時,rootfs文件夾用來存放根文件系統(tǒng),
#cd rootfs
根據(jù)根文件系統(tǒng)的基本結(jié)構(gòu),建立各個對應(yīng)的目錄:
# mkdir bin dev etc lib proc sbin tmp usr var root home
# chmod 1777 tmp
# mkdir usr/bin usr/lib usr/sbin
# ls
dev etc lib proc sbin tmp usr var
# mkdir var/lib var/lock var/log var/run var/tmp
# chmod 1777 var/tmp
對于單用戶系統(tǒng)來說,root和home并不是必須的。
準(zhǔn)備好根文件系統(tǒng)的骨架后,把前面建立的文件安裝到對應(yīng)的目錄中去。
2、拷貝鏈接庫
把uclibc的庫文件拷貝到剛才建立的lib文件夾中:
# cd ${PREFIX}/lib
[root@skynet lib]# cp *-*.so ${PRJROOT}/rootfs/lib
[root@skynet lib]# cp -d *.so.[*0-9] ${PRJROOT}/rootfs/lib
3、 拷貝內(nèi)核映像和內(nèi)核模塊
因?yàn)闆]有模塊,所以拷貝模塊就省了,
新建boot目錄,把剛才建立好的內(nèi)核拷貝過來
# cd /home/kendo/control-project/daq-module/rootfs/
# mkdir boot
# cd ${PRJROOT}/images
# cp bzImages-2.4.18-rmk5 /home/kendo/control-project/daq-module/rootfs/boot
4、 建立/dev下邊的設(shè)備文件
在linux中,所有的的設(shè)備文件都存放在/dev中,使用mknod命令創(chuàng)建基本的設(shè)備文件。
mknod命令需要root權(quán)限,不過偶本身就是用的root用戶,本來是新建了一個用戶專門用于嵌入式制作的,不過后來忘記用了……
# mknod -m 600 mem c 1 1
# mknod -m 666 null c 1 3
# mknod -m 666 zero c 1 5
# mknod -m 644 random c 1 8
# mknod -m 600 tty0 c 4 0
# mknod -m 600 tty1 c 4 1
# mknod -m 600 ttyS0 c 4 64
# mknod -m 666 tty c 5 0
# mknod -m 600 console c 5 1
基本的設(shè)備文件建立好后,再創(chuàng)建必要的符號鏈接:
# ln -s /proc/self/fd fd
# ln -s fd/0 stdin
# ln -s fd/1 stdout
# ln -s fd/2 stderr
# ls
console fd mem null random stderr stdin stdout tty tty0 tty1 ttyS0 zero
設(shè)備文件也可以不用手動創(chuàng)建,聽說RedHat /dev下的腳本MAKEDEV 可以實(shí)現(xiàn)這一功能,不過沒有試過……
基本上差不多了,不過打算用硬盤/CF卡來做存儲設(shè)備,還需要為它們建立相關(guān)文件,因?yàn)槲业腃F在目標(biāo)機(jī)器上是CF-to-IDE,可以把它們等同來對待,先看看Redhat 下邊had的相關(guān)屬性:
# ls -l /dev/hda
brw-rw---- 1 root disk 3, 0 Jan 30 2003 /dev/hda
# ls -l /dev/hda1
brw-rw---- 1 root disk 3, 1 Jan 30 2003 /dev/hda1
對比一下,可以看出,had類型是b,即塊設(shè)備,主編號為3,次編號從0遞增,根限位是
rw-rw----,即660,所以:
# mknod -m 660 hda b 3 0
# mknod -m 660 hda1 b 3 1
# mknod -m 660 hda2 b 3 2
# mknod -m 660 hda3 b 3 3
5、添加基本的應(yīng)用程序
未來系統(tǒng)的應(yīng)用程序,基本上可以分為三類:
基本系統(tǒng)工具,如ls、ifconfig這些……
一些服務(wù)程序,管理工具,如WEB、Telnet……
自己開發(fā)的應(yīng)用程序
這里先添加基本的系統(tǒng)工具,有想過把這些工具的代碼下載下來交叉編譯,不過實(shí)在是麻煩,用BusyBox,又精簡又好用……
將busybox-1.00.tar.gz下載至sysapps目錄下,解壓:
#tar zxvf busybox-1.00.tar.gz
#cd busybox-1.00
//進(jìn)入配置菜單
#make TARGET_ARCH=i386 CROSS=i386-linux- PREFIX=${PRJROOT}/rootfs menuconfig
//建立依存關(guān)系
#make TARGET_ARCH=i386 CROSS= i386-linux- PREFIX=${PRJROOT}/rootfs dep
//編譯
#make TARGET_ARCH=i386 CROSS= i386-linux- PREFIX=${PRJROOT}/rootfs
//安裝
#make TARGET_ARCH=i386 CROSS= i386-linux- PREFIX=${PRJROOT}/rootfs install
# cd ${PRJROOT}/rootfs/bin
# ls
addgroup busybox chown delgroup echo kill ls mv ping rm sleep
adduser chgrp cp deluser grep ln mkdir netstat ps rmdir umount
ash chmod date dmesg hostname login mount pidof pwd sh vi
一下子多了這么多命令……
配置busybox的說明:
A、如果編譯時選擇了:
Runtime SUID/SGID configuration via /etc/busybox.conf
系統(tǒng)每次運(yùn)行命令時,都會出現(xiàn)“Using fallback suid method ”
可以將它去掉,不過我還是在/etc為其建了一個文件busybox.conf搞定;
B、
# Do you want to build BusyBox with a Cross Compiler? (i386-linux-gcc) Cross Compiler prefix
這個指明交叉編譯器名稱(其實(shí)在編譯時的命令行已指定過了……)
C、安裝選項(xiàng)下的(${PRJROOT}/rootfs) BusyBox installation prefix,這個指明了編譯好后的工具的安裝目錄。
D、靜態(tài)編譯好還是動態(tài)編譯好?即是否選擇
[ ] Build BusyBox as a static binary (no shared libs)
動態(tài)編譯的最大好處是節(jié)省了寶貴空間,一般來說都是用動態(tài)編譯,不過我以前動態(tài)編譯出過問題(其實(shí)是庫的問題,不關(guān)busybox的事),出于慣性,我選擇了靜態(tài)編譯,為此多付出了107KB的空間。
E、其它命令,根據(jù)需要,自行權(quán)衡。
6、系統(tǒng)初始化文件
內(nèi)核啟動時,最后一個初始化動作就是啟動init程序,當(dāng)然,大多數(shù)發(fā)行套件的Linux都使用了與System V init相仿的init,可以在網(wǎng)上下載System V init套件,下載下來交叉編譯。另外,我也找到一篇寫得非常不錯的講解如何編寫初始化文件的文件,bsd-init,回頭附在后面。不過,對于嵌入式系統(tǒng)來講,BusyBox init可能更為合適,在第6步中選擇命令的時候,應(yīng)該把init編譯進(jìn)去。
#cd ${PRJROOT}/rootfs/etc
#vi inittab
我的inittal文件如下:
#指定初始化文件
::sysinit:/etc/init.d/rcS
#打開一個串口,波特率為9600
::respawn:/sbin/getty 9600 ttyS0
#啟動時執(zhí)行的shell
::respawn:/bin/sh
#重啟時動作
::restart:/sbin/init
#關(guān)機(jī)時動作,卸載所有文件系統(tǒng)
::shutdown:/bin/umount -a –r
保存退出;
再來編寫rcS腳本:
#mkdir ${PRJROOT}/rootfs/etc/init.d
#cd ${PRJROOT}/rootfs/etc/init.d
#vi rcS
我的腳本如下:
#!/bin/sh
#Set Path
PATH=/sbin:/bin
export PATH
syslogd -m 60
klogd
#install /proc
mount -n -t proc none /proc
#reinstall root file system by read/write mode(need: /etc/fstab)
mount -n -o remount,rw /
#reinstall /proc
mount -n -o remount,rw -t proc none /proc
#set lo ip address
ifconfig lo 127.0.0.1
#set eth0 ip address
#當(dāng)然,這樣子做只是權(quán)宜之計(jì),最后做的應(yīng)該是在這一步引導(dǎo)網(wǎng)絡(luò)啟動腳本,像RedHat
#那樣,自動讀取所有指定的配置文件來啟動
ifconfig eth0 192.168.0.68 netmask 255.255.255.0
#set route
#同樣的,最終這里應(yīng)該是運(yùn)行啟動路由的腳本,讀取路由配置文件
route add default gw 192.168.0.1
#還差一個運(yùn)行服務(wù)程序的腳本,哪位有現(xiàn)成的么?
#網(wǎng)卡/路由/服務(wù)這三步,事實(shí)上可以合在一步,在rcS這一步中,做一個循環(huán),運(yùn)行指定啟動目錄下的所有腳,先將就著這么做吧,確保系統(tǒng)能夠正常啟動了,再來寫這個腳本。
#set hostname
hostname MyLinux
保存退出。
編寫fstab文件
#vi fstab
我的fstab很簡單:
/dev/hda1 / ext2 defaults 1 1
none /proc proc defaults 0 0
第五章 讓MyLinux能夠啟動
前一章,我們把編譯好的內(nèi)核、應(yīng)用程序、配置文件都拷貝至rootfs目錄對應(yīng)的子目錄中去了,這一步,就是把這些文件移植至目標(biāo)機(jī)的存儲器。這里,我是先另外拿一塊硬盤,掛在我的開發(fā)機(jī)上做的測試,因?yàn)槲业谋颈居脕韺懳臋n,PC機(jī)用來做開發(fā)機(jī),已經(jīng)沒有另外的機(jī)器了……但是本章只是講述一個一般性的過程,并不影響你直接在目標(biāo)主機(jī)上的工作。
因?yàn)橐院竽繕?biāo)機(jī)識別硬盤序號都是hda,而我現(xiàn)在直接掛上去,則會是hdb、hdc……這樣,安裝lilo時有點(diǎn)麻煩(雖然也可以實(shí)現(xiàn))。所以我想了另一個辦法:
把新硬盤掛在IDE0的primary上,進(jìn)入linux后,會被認(rèn)為是had;
原來主機(jī)的裝Redhat的硬盤,我將它從IDE0的primary上變到了IDE1 的primary,因?yàn)樗膌ilo早已裝好,基本上不影響系統(tǒng)的使用;
分區(qū)和格式化
BIOS中改為從第二個硬盤啟動;也就是從我原來開發(fā)機(jī)啟動,新的硬盤被識別成了had。
#fdisk /dev/hda
用d參數(shù)刪除已存在的所有分區(qū)
用n參數(shù)新建一個分區(qū),也是就/dev/hda1
格式化
#mkfs.ext2 /dev/hda1
安裝bootloader
因?yàn)槲沂荴86平臺,所以直接用了lilo,如果你是其這平臺,當(dāng)然,有許多優(yōu)秀的bootloader供你選擇,你只需查看其相應(yīng)的說明就可以了。
編譯lilo配置文件,我的配置文件名為target.lilo.conf,置于${PRJROOT}/rootfs/etc目錄。內(nèi)容如下所示:
boot=/dev/hda
disk=/dev/hda
bios=0x80
image=/boot/bzImage-2.4.18-rmk5
label=Linux
root=/dev/hda1
append="root=/dev/hda1"
read-only
//新建文件夾,為mount做新準(zhǔn)備
#mkdir /mnt/cf
//把目標(biāo)硬盤mount上來
#mount –t ext2 /dev/hdc1 /mnt/cf
回到rootfs
#cd ${PRJROOT}/rootfs
拷貝所有文件至目標(biāo)硬盤
#cp –r * /mnt/cf
這樣,我們所有的文件都被安裝至目標(biāo)硬盤了,當(dāng)然,它還不能引導(dǎo),因?yàn)闆]有bootloader。使用如下命令:
# lilo -r /mnt/cf -C etc/target.lilo.conf
Warning: LBA32 addressing assumed
Added Linux *
-r :改變根目標(biāo)為/mnt/cf ,這樣配置文件其實(shí)就是/mnt/cf/etc/target.lilo.conf,也就是我們先前建立的文件。
當(dāng)然,完成這一步,需要lilo22.3及以后版本,如果你的版本太舊,比如Redhat9.0自帶的,就會出現(xiàn)下面的信息:
#lilo –r /mnt/cf –C etc/target.lilo.conf
Fatal: open /boot/boot.b: No such file or directory
這時,你需要升級你的lilo,或者重新安裝一個。
啟動系統(tǒng)
#umount /mnt/cf
#reboot
將BIOS改為從IDE0啟動,也就是目標(biāo)硬盤。如果一切順利,你將順利進(jìn)入一個屬于你的系統(tǒng)。
回頭再來看看我們的工作空間吧
[root@skynet lib]# df /dev/hda1
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda1 3953036 1628 3750600 1% /mnt/cf
總共花去了我1628KB的空間,看來是沒有辦法放到軟盤里邊去了^o^,不過一味求小,并不是我的目標(biāo)。
[root@skynet skynet]# ls ${PRJROOT}
bootloader build-tools debug doc images kernel rootfs sysapps tmp tools
這幾個目錄中的文件,呵呵,與本文一開頭規(guī)劃的一樣
[root@skynet skynet]# ls build-tools/
buildroot buildroot-0.9.27.tar.tar
包含了buildroot源碼及壓縮包,事實(shí)上buildroot下邊還包括了GNU其它工具的源碼、編譯文件等諸多內(nèi)容,是我們最重要的一個文件夾,不過到現(xiàn)在它已經(jīng)沒有多大用處了,如果你喜歡,可以將它刪除掉(不建議)。
[root@skynet skynet]# ls images
2.4.18-rmk5 bzImage-2.4.18-rmk5 System-2.4.18-rmk5 vmlinux-2.4.18-rmk5
內(nèi)核映像及配置文件等,如果你有模塊,因?yàn)檫有相應(yīng)的目錄
[root@skynet skynet]# ls kernel/
linux-2.4.27 linux-2.4.27.tar.bz2
內(nèi)核源碼及壓縮包
[root@skynet skynet]# ls rootfs/
bin boot dev etc home lib linuxrc proc root sbin tmp usr var
制作好的根文件系統(tǒng),重中之重,注意備份……
[root@skynet skynet]# ls sysapps/
busybox-1.00 busybox-1.00.tar.gz
busybox-1.00源碼包,或許你還要繼續(xù)添加/刪除一些命令……
[root@skynet skynet]# ls tools
bin i386-linux i386-linux-uclibc include info lib man
這個也很重要,我們制作好的交叉開發(fā)工具鏈。如果你要繼續(xù)開發(fā)程序,這個目錄重要性就很高了。
其它目錄暫時是空的。
第六章 完善MyLinux
關(guān)于進(jìn)一步的調(diào)試,你可以在開發(fā)機(jī)上使用chroot /mnt/cf /bin/sh這樣的命令,以使我們在目標(biāo)根文件系統(tǒng)上工作。
支持多用戶
因?yàn)槲以诰幾gbusybox時,已經(jīng)將它的多用戶那一大堆命令編譯了進(jìn)來,F(xiàn)在關(guān)鍵是的要為其建立相應(yīng)的文件;
進(jìn)入原來的開發(fā)機(jī),進(jìn)入rootfs目錄,切換根目錄
#chroot rootfs/ /bin/sh
A、 建立/etc/passwd文件,我的文件內(nèi)容如下:
root:0:0:root:/root:/bin/bash
B、 建立/etc/group文件,我的文件內(nèi)容如下:
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
disk:x:7:
C、 為root建立密碼
#passwd root
試試用addgroup/addusr……這堆命令。然后重啟,從目標(biāo)硬盤上啟動;從console口,9600登陸試試(因?yàn)槲以趇nittab中啟用了ttyS0,我未來的目標(biāo)機(jī),是沒有顯卡的,需要從console口或SSH進(jìn)去管理)
MyLinux login: root
Password:
BusyBox v1.00 (2004.10.10-04:43+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
~ #
成功了……
增加WEB Server
Busybox里邊有httpd選項(xiàng),不過我編譯時并沒有選擇,所以還是自己來安裝。我使用的軟件是thttpd-2.25b.tar.gz,將它移至sysapps目錄下。
[root@skynet sysapps]# tar zxvf thttpd-2.25b.tar.gz
[root@skynet sysapps]# cd thttpd-2.25b
//配置
[root@skynet thttpd-2.25b]# CC=i386-linux-gcc ./configure --host=$TARGET
……
i386-linux-gcc -static htpasswd.o -o htpasswd -lcrypt
make[1]: warning: Clock skew detected. Your build may be incomplete.
make[1]: Leaving directory `/home/skynet/sysapps/thttpd-2.25b/extras'
//拷貝至根文件目錄
[root@skynet thttpd-2.25b]# cp thttpd ${PRJROOT}/rootfs/usr/sbin
//trip處理
[root@skynet thttpd-2.25b]# i386-linux-strip ${PRJROOT}/rootfs/usr/sbin/thttpd
本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u/3166/showart_67519.html |
|