一個典型的桌面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的時候會看見屏幕打印信息。 更多內容請看系統管理專題,或