一個典型的桌面Linux系統包括3個主要的軟體層---linux核心、C庫和應用程式代碼。
核心是唯一可以完全控制硬體的層,核心驅動程式代表應用程式與硬體之間進行會話。核心之上是C庫,負責把POSIX API轉換為核心可以識别的形式,然後調用核心,從應用程式向核心傳遞參數。應用程式依靠驅動核心來完成特定的任務。
在設計嵌入式應用的時候,可以不按照這種層次,應用程式越過C庫直接和核心會話,或者把應用和核心捆綁在一起,甚至可以把應用寫為核心的一個線程,在核心 中運作,雖然這樣在移植上帶來了困難,但考慮嵌入式系統對尺寸要求小的特點,是完全可行的。不過我們使用三層軟體結構的模式來學習嵌入式linux将會是 我們認識更清晰,簡單可行并使應用具有彈性。
快速入門
最簡單的建立嵌入式Linux應用的方法就是從我們使用的桌面Linux入手,安裝一個喜愛的版本,把我們的某個應用作為初始化的一部分,架構就算完成了。
當然,嵌入式linux應用遠比我們的桌面版本功能簡單專一,它也許就是一個用于足彩的終端機,或是一個數位音頻播放器,這些系統除了使用嵌入式CPU外,僅僅再需要一個序列槽,網口等少量的輸入輸出接口就可以完成它們特定的應用了。
在軟體上,它可以按照三層的概念由核心裝載器,定制的核心和較少的為特定任務設計的靜态連接配接的應用程式組成。之是以使用靜态連接配接的應用程式,是因為少量的 靜态連接配接程式所要的存儲空間,比同樣數量的動态連接配接的程式所占的空間小,這個平衡點需要我們在實際開發中去擷取。也許你正在設計的是個PDA,它的應用程 序較多,那麼你很可能就要使用動态連接配接程式來減少存儲空間。在你的/bin或者/sbin目錄下,用廠清單看看bash,ifconfig,vi..., 也許隻用幾十K,當你運作 ldd /bin/bash 時,你會看到它們都和好幾個庫檔案相連。好了,這樣看來,我們得把PC想像成一個嵌入式硬體平台,再重新制作一個特定功能的嵌入式linux。
基礎知識
再進行實際操作之前,先來搞清楚幾個基礎知識。
核心裝載器Loader,它的作用是把核心從外部存儲器,移動到記憶體中。它隻作這個事情,一旦完成了調入核心的工作,Loader就跳轉到核心位置開始執 行。不同架構有不同的 Loader,在x86結構的PC上,通常使用的loader有LILO,GRUB,syslinux,syslinux在嵌入式linux中也同樣工 作。其他非x86架構的應用中,你必須使用專門的loader,或者自己編寫loader來裝入核心。也有不使用loader的情況,系統加電以後,核心 直接從燒錄有映象的Flash上開始執行。
核心,一旦核心開始執行,它将通過驅動程式初始化所有硬體,這可以從我們的pc機螢幕的輸出看出來,每個驅動程式都列印一些有關它的資訊。初始化完成 後,計算機就準備運作嵌入式應用。也許一個,也許是多個應用程式組成了嵌入式應用,但通常首先調用的是init(通過loader 向核心傳入init=/program 可以定制首先運作的程式)。桌面linux中,init會讀取/etc/inittab檔案,來決定執行級别和哪些腳本和指令。嵌入式應用中,可以根據實 際的情況決定是否使用标準的init執行方式,也許這個init是個靜态程式,它能夠完成我們的嵌入應用的特定任務,那完全不用考慮inittab了。
initrd檔案系統,initrd以一種把核心從存儲媒體裝入到記憶體的相同的機制來裝入一個小型檔案系統。這個檔案系統最好是以壓縮的方式存儲在媒體上 的,解壓縮到RAM盤上。通過使用initrd,包含有核心驅動和啟動腳本的小檔案系統,就可以直接從媒體上和核心一起啟動起來,核心屆壓縮這個檔案系 統,并執行這個檔案系統上叫做/linuxrc的腳本檔案,這個腳本通常會把啟動過程中所需要的驅動程式裝入。腳本退出以後,initrd檔案系統也卸下 了,啟動過程進入真正初始化過程。對于嵌入式來講,可以将需要的應用軟體都運作在這個 initrd檔案系統上,隻要/linxrc檔案不結束,核心啟動過程的其他部分就不會繼續。
做個試驗:
cp /boot/initrd-2.4.20.img /tmp
cd /tmp
mv initrd-2.4.2-.img initrd.img.gz
gunzip initrd.img.gz
mount -o loop initrd.img /mnt
cd /mnt
ls
cat linuxrc 可以看到裡面執行了加載了兩個子產品的操作,你在啟動linxu的時候會看見螢幕列印資訊。
入門試驗,制作一個簡單的應用
我們使用一張軟碟啟動一台假象的隻有一個序列槽,鍵盤輸入,顯示輸出的x86架構的linux系統,執行的特定應用就是運作minicom,通過序列槽撥号。
需要軟體: minicom-xx.src.tar.gz 和 syslinux-xx.tar.gz,xx代表版本号,開始之前,在主目錄建立一個目錄,來釋放這兩個軟體包:
cd
mkdir -p project/minilinux
cd project/minilinux
tar zxvf minicom-xx.src.tar.gz
tar zxvf syslinux-xx.tar.gz
1、裁減linux核心(需要系統安裝核心檔案包)
配置核心的時候,我們需要選擇這些:摸塊編入核心,386處理器、實體記憶體off、支援 ELF、标準PC軟碟、支援RAM盤(4096)、支援 initial RAM disk (initrd)、虛你終端、虛拟終端控制台、标準序列槽、ext2檔案系統、控制台驅動,VGA text console、DOS FAT、MSDOS檔案系統,其他的都可以不要,這樣核心編出來較小。
步驟:
cd /usr/src/linux
make mrproper
make xconfig
make dep && make bzImage
得到 /usr/src/linux/arch/i386/boot/目錄的核心檔案bzIamge。
2、編譯一個靜态的minicom ,把它作為将來的linuxrc
cd minicom-xx/src
vi Makefile
修改下面這行
minicom: $(minicom_OBJECTS) $(minicom_DEPENDENCIES)
rm -f minicom 下面的行加上 -static,連接配接為靜态程式
(LINK) -static $(minicom_LDFLAGS) $(minicom_OBJECTS) $(minicom_LDADD) $(LIBS)
vi minicom.c
找到 if (real_uid==0 && dosetup==0 ) 删除這個判斷條件語句,主要是用于權限判斷的,因為這個嵌入應用不關注權限問題,否則會出錯。
make
得到可執行程式,用ldd 檢查一下是不是靜态程式。
3、準備initrd壓縮檔案image.gz
dd if=/dev/zero of=image bs=1k count=4096
losetup /dev/loop0 image
mke2fs -m 0 /dev/loop0
mounmt -t ext2 /dev/loop0 /mnt/
mkdir -p /mnt/dev
mkdir -p /mnt/usr/share/terminfo/l/
cd /dev
cp -a consle null tty tty0 zero mem /mnt/dev
cp -P /usr/share/terminfo/l/linux /mnt/usr/share/terminfo/l/linux
cp ~/project/minilinux/mincom/src/minicom /mnt/linuxrc
umount /mnt
losetup -d /dev/loop0
sync
gzip -9 image
4、制作軟碟引導,并拷貝檔案 bzimage image.gz 到軟碟
A.使用grub
fdformat /dev/fd0
mke2fs /dev/fd0
mount /mnt/fd0 /mnt/floppy
mkdir -p /mnt/floppy/boot/grub
cp /boot/grub/stage1 /boot/grub/stage2 /mnt/floppy/boot/grub
執行 grub,在軟碟上建立引導
grub > root (fd0)
grub > setup (fd0)
grub > quit
cp /usr/src/linux/arch/i386/boot/bzImge /mnt/floppy
cp ~/porject/minilinux/image.gz /mnt/floppy
編輯 /mnt/floppy/boot/grub/grub.conf
default =0
timeout-=10
title minilinux
root (fd0)
kernel /bzImage
initrd /image.gz
卸下軟碟
umount /mnt/floppy
B. 使用syslinux
mkfs.msdos /dev/fd0
mount -t msdos /dev/fd0 /mnt/floppy
cp syslinux-xx/ldlinxu.sys /mnt/floppy
cat > /mnt/floppy/syslinux.cfg
LABEL linux
KERNEL bzimage
APPEND initrd=image.gz
umont /mnt/floppy
syslinux-xx/syslinux /dev/fd0
5、用軟碟啟動計算機,如果幸運,minicom的運作畫面出現在螢幕上。
到此,我們的單應用嵌入式linux做好了,但它還很簡陋,沒有什麼實際用途,但通過這個實驗,可以了解嵌入式系統的大緻結構和開發過程。在進行實際的嵌 入式開發時,通常要在PC機上借助嵌入式linux開發工具包,如:uclinux, bluecat等,對相應的硬體平台(目标機)進行軟體編寫編譯,調試成功後,将核心及應用程式寫入到目标機的存儲器中,進而完成整個應用。