嵌入式Linux由一個幾百KB的kernel(內(nèi)核)和一些根據(jù)需要進(jìn)行定制的系統(tǒng)模塊組成。由于Linux是開放源代 碼的操作系統(tǒng),因此,其在嵌入式領(lǐng)域有其不可替代的成本和高度靈活性等優(yōu)勢。
將Linux系統(tǒng)裁減到就像DOS一樣只要一張軟盤就能啟動,是制作嵌入式Linux的基礎(chǔ)。網(wǎng)絡(luò)上有許多實現(xiàn)方法 的介紹,但是在實踐過程中都或多或少存在著一些問題或不方便之處。我們結(jié)合自己在這方面的實踐經(jīng)驗,詳細(xì)介紹基于軟盤Linux的制作過程。
三個基本元素
一個嵌入式Linux系統(tǒng)只需要下面三個基本元素:引導(dǎo)程序、Linux微內(nèi)核(由內(nèi)存管理、進(jìn)程管理和事務(wù)處理 構(gòu)成)和初始化進(jìn)程。如果要讓它有更多的功能且保持小型化,還可以加上文件系統(tǒng)、TCP/IP網(wǎng)絡(luò)支持、GUI(圖形用戶界面)和設(shè)計精簡的應(yīng)用程序,并將其放在ROM、RAM、FLASH或Disk On Chip中啟動。由于嵌入式Linux操作系統(tǒng)的高度靈活性,開發(fā)者可以很容易地對它進(jìn)行定制或作適當(dāng)開發(fā),來滿足實際應(yīng)用需要。
將Linux的系統(tǒng)裁減到只要一張軟盤就能啟動,不但是制作嵌入式Linux的基礎(chǔ),而且自己也有廣泛的應(yīng)用前景。 這些應(yīng)用包括簡單路由器管理、三層交換機(jī)管理、floppy-boot防火墻管理等。國外有專門的組織致力于這方面的工作,如LOAF(Linux on a floopy)等組織。
選擇內(nèi)核
創(chuàng)建一個啟動盤首先必須創(chuàng)建系統(tǒng)內(nèi)核。由于軟盤容量有限,因此常采用對內(nèi)核進(jìn)行手工配置,去掉不必要的模塊的方法來裁減內(nèi)核。
要想裁減內(nèi)核體積,創(chuàng)建它時就得把不必要的功能去掉,如去掉對網(wǎng)絡(luò)的支持和對不必要設(shè)備的支持。但是一定要記住保留內(nèi)核對RAMDISK和ext2的支持,否則啟動盤將不能工作。其過程如下:
1)以root超級用戶登錄,進(jìn)入目錄/usr/src/linux。
2)執(zhí)行#make menuconfig來對內(nèi)核模塊進(jìn)行配置(也可以在X Window中運行make xconfig)。
3)依次執(zhí)行#make dep和#make bzImage (如果內(nèi)核不大則執(zhí)行#make zImage),執(zhí)行該命令后,將在 /usr/src/linux/arch/i386/boot目錄下生成內(nèi)核文件bzImage(或zImage)。若配置中加入了模塊的支持(選項為M),還需要執(zhí)行#make modules和#make modules_install。
4)用命令#cp usr/src/linux/arch/i386/ boot/bzImage /boot拷貝新內(nèi)核到/boot目錄,修改文件
/etc/lilo.conf,加入:
image = /boot/bzImage
label = new
root =/dev/hdxx(你自己的啟動硬盤分區(qū))
read-only
執(zhí)行命令#lilo載入新內(nèi)核,#reboot重啟系統(tǒng),在出現(xiàn)“l(fā)ilo:”時鍵入new。若系統(tǒng)正常引導(dǎo),則執(zhí)行下一步, 若不行則用老內(nèi)核引導(dǎo)后,到步驟1)重新配置編譯內(nèi)核。
5)插入軟盤執(zhí)行
#dd bs=1k if=/usr/src/linux/arch/i386/ boot/bzImage of=/dev/fd0
這樣將內(nèi)核拷貝到軟盤上。
6)用命令#ls -s將在/usr/src/linux/ arch/i386/boot/bzImage得到內(nèi)核的大小(假定為476),將這個大小記錄下來以備后用。
這樣就制作了包含裁減內(nèi)核的可供啟動的Linux啟動軟盤。但是由于沒有root文件系統(tǒng),使用這張軟盤啟動系統(tǒng)后,系統(tǒng)會顯示“VFS: cannot open root device x:x”和
“kernel panic: VFS: unalbe to boot root fs on x:x”的錯誤。
root文件系統(tǒng)
一個root文件系統(tǒng)必須包括支持完整Linux系統(tǒng)的全部東西,因此,它至少應(yīng)包括:基本文件系統(tǒng)結(jié)構(gòu);至少含有目錄/dev、/proc、/bin、/etc、/lib、/usr、/tmp;最基本的應(yīng)用程序,如sh、ls、cp、mv等;最低限度的 配置文件,如rc、inittab、fstab等;設(shè)備:/dev/hd*、/dev/ tty*、/dev/fd0;基本程序運行所需的函數(shù)庫。
由于以上所需文件遠(yuǎn)超過1.44M,因此我們通常的做法是在準(zhǔn)備好內(nèi)容后將其壓縮到軟盤中。當(dāng)用軟盤啟動時,再把文件解壓到內(nèi)存中,形成一個虛擬盤(RAMDISK),通過RAMDISK控制系統(tǒng)啟動。如果你使用LILO控制啟動,先檢
查一下LILO的配置文件/etc/lilo.conf中定義的RAMDISK的大?。?nbsp;
RAMDISK_SIZE = nnn
創(chuàng)建root文件系統(tǒng)
回到根目錄或用戶的缺省目錄,用#mkdir flop建立工作目錄flop。在這個目錄下用mkdir建立以下一些目錄:
/dev,設(shè)備;/proc - proc,文件系統(tǒng)所需目錄;/etc,系統(tǒng)配置文件;/sbin,重要的系統(tǒng)程序;/bin,基本應(yīng) 用程序;/lib,共享函數(shù)庫;/mnt,裝載其他磁盤節(jié)點;/usr,附加應(yīng)用程序。
其中/proc、/mnt和/usr在此情況下都是空的,只需要用mkdir創(chuàng)建它們即可。其余的目錄應(yīng)根據(jù)需要分別創(chuàng)建。
下面對它們一個一個地詳細(xì)敘述。
/dev:這個目錄中含有系統(tǒng)不可缺少的設(shè)備文件。你可以把現(xiàn)有系統(tǒng)中/dev的文件拷貝過來,然后刪除不必要的文件。不過一定要保留console、kmem、mem、null、ram、tty*等文件。其余的都可以根據(jù)需要刪除。
/etc:這個目錄中含有一些必不可少的系統(tǒng)配置文件。一般可以包含rc.d/* (系統(tǒng)啟動腳本)、fstab(列出要登錄的文件系統(tǒng))、inittab(包含啟動過程參數(shù))、passwd (用戶名和目錄)、group(用戶組)、shadow(用戶加密密碼)。
如果不使用init作為登錄進(jìn)程,而將init鏈接到/bin/bash,則/etc目錄下可以不含有任何文件。
/bin和/sbin:該目錄中包含有必不可少的應(yīng)用程序,如ls、mv、cat、cp、getty(mingettty)。也可以根據(jù)自己的需要選擇,不過一定要記住包括以下程序:init、getty、login、mount、bash。
/lib:該目錄中包含有你的啟動盤啟動過程中所需要的共享函數(shù)庫。在/lib目錄下還必須有函數(shù)庫裝載器,這個裝載器或是ld.so (對a.out庫)或是ld-linux.so (對ELF庫)。
模塊
如果有一個模塊化的內(nèi)核,你還得必須考慮需要加載的模塊。它們都位于/lib/modules。你可以把不是很重要的模塊放到別的盤上,當(dāng)系統(tǒng)啟動后再加載,這樣會節(jié)省啟動盤的空間。
打包
1)建立loop設(shè)備的臨時掛接點和一個大小為4.6兆(大小可以調(diào)節(jié))的臨時文件,并將其清零:
#mkdir /mnt/loop 2>/dev/null
#dd if=/dev/zero of=/tmp/loop_tmp bs=1k count=4600 >/dev/null
2)將loop設(shè)備與臨時文件聯(lián)系起來
#losetup /dev/loop0 /tmp/loop_tmp
3)Linux內(nèi)核識別兩種可以直接拷貝到RAMDISK的文件系統(tǒng),它們是minix和ext2,ext2性能更好:
#mke2fs -m 0 /dev/loop0 2>/dev/null
#mke2fs將會自動判斷設(shè)備容量的大小并相應(yīng)地配置自身,-m 0參數(shù)防止它給root保留空間,這樣會騰出更多
的有用空間。
4)接著把虛擬盤掛在節(jié)點/mnt上:
#mount /dev/loop0 /mnt/loop -t ext2
5)將制作好的root文件系統(tǒng)拷貝到所掛的節(jié)點上,卸下掛接點,刪除建立的掛接點,再取消loop設(shè)備與臨時掛接點的聯(lián)系。
#cp -a ./tree/* /mnt/loop
#umount /mnt/loop
#rmdir /mnt/loop 2>/dev/null
#losetup -d /dev/loop0
6)壓縮文件系統(tǒng)后,就擁有了一個壓縮的root文件系統(tǒng),刪除建立的臨時文件。
#dd if=/tmp/loop_tmp | gzip -9 > rootfs.gz
#rm -f /tmp/loop_tmp
7)檢查壓縮后的root文件系統(tǒng)的大小,如果大了,還得去掉一些東西。
#ls -s ./zImage|cut -f2 -d
整合
有了root文件系統(tǒng)和內(nèi)核之后,最后的工作就是把它們整合在一起。
先檢查總文件的大小,包括已經(jīng)制作的內(nèi)核和打包的root文件系統(tǒng)。如果超出1.44M,就得考慮重新創(chuàng)建。root文 件系統(tǒng)所需的所有文件都準(zhǔn)備就緒,你就可以運行它了,運行結(jié)果應(yīng)該沒有錯誤,否則就應(yīng)該仔細(xì)檢查一下。
真正的嵌入式Linux系統(tǒng)
到這里基于軟盤的Linux盤已經(jīng)做好了,剩下的工作就是測試這張盤的正確性,如果有問題還得從頭再來。
現(xiàn)在許多Linux的發(fā)行套件中都有廠家做好的啟動盤,它們的制做原理和以上介紹的大同小異,但是它們常常使用 許多不同的技巧,因為它們要面對更多的硬件和各種可能發(fā)生的情況。
真正的基于IA應(yīng)用的嵌入式Linux還必須加入GUI(圖形用戶界面)和設(shè)計精簡的應(yīng)用程序,如網(wǎng)絡(luò)瀏覽器等。GUI方面開放源代碼的,國外有Microwindows(可訪問www.microwindows.org),國內(nèi)有miniGUI(可訪問 www.minigui.org )。
它們的源代碼都可以在網(wǎng)上找到。瀏覽器方面用得較廣的是ViewMLwww.viewml.org),它也是開放源代碼的。結(jié)合以上一些工具,再加上對硬件驅(qū)動程序的開發(fā),就可以形成一套嵌入式的Linux操作系統(tǒng)。