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