什么是Uclinux?
uCLinux是一個(gè)完全符合GNU/GPL公約的項(xiàng)目,完全開放代碼,現(xiàn)由Lineo公司支持維護(hù)。英文單詞中u表示Micro,小的意思,C表示Control,控制的意思,所以u(píng)CLinux就是Micro-Control-Linux,字面上的理解就是“微控制領(lǐng)域中的Linux系統(tǒng)”。它專門針對(duì)沒有MMU的CPU,并專為嵌入式系統(tǒng)做了許多小型化的工作,已支持前面提到的多款CPU。官方主頁(yè)在http://www.uclinux.org。國(guó)內(nèi)從事uclinux開發(fā)有合肥華恒科技等幾家公司 。
核心開發(fā)人員12人左右。To join, send mail to majordomo@uclinux.org with the command "subscribe uclinux-dev" in the body of the message.
已成功使用uCLinux的案例
合肥華恒的基于coldfire 5272/5407的家庭網(wǎng)關(guān)Soho/Home/VPN Router、基于68EZ328的PDA開發(fā)套件
Maple?信號(hào)處理公司基于DragonBallVZ和TMS320C541xx?DSP的DAQStick?系列嵌入式信號(hào)處理板卡
珠海萬禾的基于VZ328的多串口設(shè)備Webport2000,基于68VZ328的PDA開發(fā)套件
Lineo 公司的uCsimm、uCdimm開發(fā)套件以及商業(yè)音樂媒體服務(wù)器BMMS-MP3.COM采用
西南交通大學(xué)電氣檢測(cè)與故障診斷信息研究室的嵌入式電力設(shè)備運(yùn)行狀態(tài)監(jiān)測(cè)系統(tǒng)
NetSilicon公司 NET+Works設(shè)備網(wǎng)絡(luò)平臺(tái)(基于ARM7TDMI)-為Wireless Networks 公司的BlueLAN 提供接入點(diǎn)
東軟的智能家庭網(wǎng)關(guān)產(chǎn)品
愛立信的基于ARM7TDMI藍(lán)芽BLIP無線通信設(shè)備
基于ARM7TDMI的Aplio公司的voice-over-IP電話
AXIS公司的AXIS2001網(wǎng)絡(luò)數(shù)碼相機(jī)
Adomo公司的家庭機(jī)頂盒
Snapsear的VPN安全設(shè)備
瑞士洛桑的Smartdata公司的微型計(jì)算機(jī)Chipslice
uCLinux內(nèi)存管理
uClinux同標(biāo)準(zhǔn)Linux的最大區(qū)別就在于內(nèi)存管理????????標(biāo)準(zhǔn)Linux使用的虛擬存儲(chǔ)器技術(shù)
?◇標(biāo)準(zhǔn)Linux是針對(duì)有內(nèi)存管理單元的處理器設(shè)計(jì)的。虛擬地址被送到內(nèi)存管理單元(MMU),把虛擬地址映射為物理地址。采用分頁(yè)的方式來載入進(jìn)程。實(shí)際存儲(chǔ)器分割為相同大小的頁(yè)面。
◇虛擬存儲(chǔ)器由存儲(chǔ)器管理機(jī)制及一個(gè)大容量的快速硬盤存儲(chǔ)器支持。它的實(shí)現(xiàn)基于局部性原理,當(dāng)一個(gè)程序在運(yùn)行之前,沒有必要全部裝入內(nèi)存,而是僅將那些當(dāng)前要運(yùn)行的那些部分頁(yè)面裝入內(nèi)存運(yùn)行(copy-on-write),其余暫時(shí)留在硬盤上程序運(yùn)行時(shí)如果它所要訪問的頁(yè)已存在,則程序繼續(xù)運(yùn)行,如果發(fā)現(xiàn)不存在的頁(yè),操作系統(tǒng)將產(chǎn)生一個(gè)頁(yè)失效異常,導(dǎo)致操作系統(tǒng)把需要運(yùn)行的部分加載到內(nèi)存中。必要時(shí)操作系統(tǒng)還可以把不需要的內(nèi)存頁(yè)交換到磁盤上。
?◇通過賦予每個(gè)任務(wù)不同的虛擬--物理地址轉(zhuǎn)換映射(頁(yè)表),還可支持不同任務(wù)之間的保護(hù)、共享等。
?◇對(duì)于多進(jìn)程管理當(dāng)處理器進(jìn)行進(jìn)程切換并執(zhí)行一個(gè)新任務(wù)時(shí),一個(gè)重要部分就是為新任務(wù)切換頁(yè)表。
標(biāo)準(zhǔn)Linux系統(tǒng)的內(nèi)存管理功能??
◇可以運(yùn)行只加載了部分的程序,縮短了程序啟動(dòng)的時(shí)間
??? ◇運(yùn)行比內(nèi)存還要大的程序。理想情況下應(yīng)該可以運(yùn)行任意大小的程序 ◇可以使多個(gè)程序同時(shí)駐留在內(nèi)存中提高CPU的利用率 ◇可以運(yùn)行重定位程序。即程序可以方于內(nèi)存中的任何一處,而且可以在執(zhí)行過程中移動(dòng) ◇寫機(jī)器無關(guān)的代碼。程序不必事先約定機(jī)器的配置情況 ◇減輕程序員分配和管理內(nèi)存資源的負(fù)擔(dān)
???? ◇可以進(jìn)行程序代碼共享 ◇提供內(nèi)存保護(hù),進(jìn)程不能以非授權(quán)方式訪問或修改頁(yè)面,內(nèi)核保護(hù)單個(gè)進(jìn)程的數(shù)據(jù)和代碼以防止其它進(jìn)程修改它們。否則,用戶程序可能會(huì)偶然(或惡意)的破壞內(nèi)核或其它用戶程序
??? 代價(jià):內(nèi)存管理需要地址轉(zhuǎn)換表和其他一些數(shù)據(jù)結(jié)構(gòu),留給程序的內(nèi)存減少了。地址轉(zhuǎn)換增加了每條指令的執(zhí)行時(shí)間,而對(duì)于有額外內(nèi)存操作的指令會(huì)更嚴(yán)重。當(dāng)進(jìn)程訪問不在內(nèi)存的頁(yè)面時(shí),系統(tǒng)處理失效的磁盤I/O操作極耗時(shí)間。
uCLinux針對(duì)NOMMU的特殊處理
uClinux針對(duì)沒有MMU的處理器設(shè)計(jì),不能使用處理器的虛擬內(nèi)存管理技術(shù),但出現(xiàn)簡(jiǎn)單和盡量靠攏標(biāo)準(zhǔn)Linux得需要,uClinux仍然沿用標(biāo)準(zhǔn)Linux的分頁(yè)內(nèi)存管理結(jié)構(gòu),系統(tǒng)在啟動(dòng)時(shí)把實(shí)際存儲(chǔ)器進(jìn)行分頁(yè),但實(shí)際上采用的是實(shí)存儲(chǔ)器管理策略。
uClinux系統(tǒng)對(duì)于內(nèi)存的訪問是直接的,(它對(duì)地址的訪問不需要經(jīng)過MMU,而是直接送到地址線上輸出),所有程序中訪問的地址都是實(shí)際的物理地址。
操作系統(tǒng)對(duì)內(nèi)存空間沒有保護(hù)(這實(shí)際上是很多嵌入式系統(tǒng)的特點(diǎn)),各個(gè)進(jìn)程實(shí)際上共享一個(gè)運(yùn)行空間(沒有獨(dú)立的地址轉(zhuǎn)換表)。
一個(gè)進(jìn)程在執(zhí)行前,系統(tǒng)必須為進(jìn)程分配足夠的連續(xù)地址空間,然后全部載入主存儲(chǔ)器的連續(xù)空間中。由于程序加載地址與預(yù)期(ld文件中指出的)通常都不相同,這樣relocation過程就是必須的。
磁盤交換空間無法使用的,系統(tǒng)執(zhí)行時(shí)如果缺少內(nèi)存將無法通過磁盤交換來得到改善。
uCLinux對(duì)開發(fā)人員提出的更高要求
從易用性來說,uClinux的內(nèi)存管理實(shí)際上是一種倒退,退回了到了UNIX早期或是Dos系統(tǒng)時(shí)代。開發(fā)人員不得不參與系統(tǒng)的內(nèi)存管理。從編譯內(nèi)核開始,開發(fā)人員必須告訴系統(tǒng)這塊開發(fā)板到底擁有多少的內(nèi)存。
由于應(yīng)用程序加載時(shí)必須分配連續(xù)的地址空間,而針對(duì)可連續(xù)地址分配內(nèi)存大小是受限的,開發(fā)人員在開發(fā)應(yīng)用程序時(shí)必須考慮內(nèi)存的分配情況并關(guān)注應(yīng)用程序需要運(yùn)行空間的大小。另外由于采用實(shí)存儲(chǔ)器管理策略,
用戶程序同內(nèi)核以及其它用戶程序在一個(gè)地址空間,程序開發(fā)時(shí)要保證不侵犯其它程序的地址空間,以使得程序不至于破壞系統(tǒng)的正常工作,或?qū)е缕渌绦虻倪\(yùn)行異常。從內(nèi)存的訪問角度來看,開發(fā)人員的權(quán)利增大了(開發(fā)人員在編程時(shí)可以訪問任意的地址空間),但與此同時(shí)系統(tǒng)的安全性也大為下降。
從嵌入式設(shè)備實(shí)現(xiàn)的功能來看,嵌入式設(shè)備通常在某一特定的環(huán)境下運(yùn)行,只要實(shí)現(xiàn)特定的功能,其功能相對(duì)簡(jiǎn)單,內(nèi)存管理的要求完全可以由開發(fā)人員考慮。
uCLinux內(nèi)核加載方式
?? uCLinux的內(nèi)核有兩種可選的運(yùn)行方式:可以在flash上直接運(yùn)行,也可以加載到內(nèi)存中運(yùn)行。后者可以減少內(nèi)存需要。 ??? Flash運(yùn)行方式(XIP):把內(nèi)核的可執(zhí)行映像燒寫到flash上,系統(tǒng)啟動(dòng)時(shí)從flash的某個(gè)地址開始逐句執(zhí)行。這種方法實(shí)際上是很多嵌入式系統(tǒng)采用的方法。 ??? 內(nèi)核加載方式:把內(nèi)核的壓縮文件存放在flash上,系統(tǒng)啟動(dòng)時(shí)讀取壓縮文件在內(nèi)存里解壓,然后開始執(zhí)行,這種方式相對(duì)復(fù)雜一些,但是運(yùn)行速度可能更快(RAM的存取速率要比Flash高)。
uCLinux根(root)文件系統(tǒng)
?? uCLinux系統(tǒng)采用romfs文件系統(tǒng),這種文件系統(tǒng)相對(duì)于一般的ext2文件系統(tǒng)要求更少的空間。空間的節(jié)約來自于兩個(gè)方面:首先內(nèi)核支持romfs文件系統(tǒng)比支持ext2文件系統(tǒng)需要更少的代碼;其次romfs文件系統(tǒng)相對(duì)簡(jiǎn)單,在建立文件系統(tǒng)超級(jí)塊(superblock)需要更少的存儲(chǔ)空間。Romfs文件系統(tǒng)不支持動(dòng)態(tài)擦寫保存,對(duì)于系統(tǒng)需要?jiǎng)討B(tài)保存的數(shù)據(jù)采用虛擬ram盤/JFFS的方法進(jìn)行處理(ram盤將采用ext2文件系統(tǒng))。
uCLinux應(yīng)用程序庫(kù)
uCLinux小型化的另一個(gè)做法是重寫了應(yīng)用程序庫(kù),相對(duì)于越來越大且越來越全的glibc庫(kù),uClibc對(duì)libc做了精簡(jiǎn)。 http://uclibc.org/uClibc.html
uClibm數(shù)學(xué)庫(kù)
uCLinux對(duì)用戶程序采用靜態(tài)鏈接的形式,這種做法會(huì)使應(yīng)用程序變大,但是基于內(nèi)存管理的問題,也就是基于沒有MMU的特性,只能這樣做,同時(shí)這種做法也更接近于通常嵌入式系統(tǒng)的做法。
標(biāo)準(zhǔn)Linux系統(tǒng)系統(tǒng)數(shù)據(jù)段,代碼段,堆和棧在虛存層面是連續(xù)的。堆向上增長(zhǎng),棧向下增長(zhǎng),在堆底和棧頂之間有256MB的內(nèi)存可供分配。uClinux采用了實(shí)內(nèi)存模式,各個(gè)內(nèi)存段在物理內(nèi)存層面是連續(xù)的,棧段在同數(shù)據(jù)段在一起,堆有系統(tǒng)內(nèi)存管理,所有進(jìn)程共享,由于內(nèi)存連續(xù)和保護(hù)的要求,棧段,數(shù)據(jù)段,代碼段都是在程序加載是分配。 這種內(nèi)存空間布局阻礙了動(dòng)態(tài)連接庫(kù)的運(yùn)用。棧段的大小固定(在生成應(yīng)用時(shí)可以指定棧段大?。?,開發(fā)人員在開發(fā)時(shí)不得不使用一些方法估計(jì)判斷棧段的大小,使其即能滿足程序的需要,又不浪費(fèi)內(nèi)存。
?uClinux可執(zhí)行文件格式
? uCLinux系統(tǒng)使用flat可執(zhí)行文件格式,目前也支持elf文件格式。先解釋幾種可執(zhí)行文件格式。 coff(common object file format):一種通用的對(duì)象文件格式; elf(executive linked file):一種為L(zhǎng)inux系統(tǒng)所采用的通用文件格式,支持動(dòng)態(tài)連接和重定位; flat:elf格式有很大的文件頭,flat文件對(duì)文件頭和一些段信息做了簡(jiǎn)化,可執(zhí)行程序小。
? 當(dāng)用戶執(zhí)行一個(gè)應(yīng)用時(shí),內(nèi)核的執(zhí)行文件加載器將對(duì)flat文件進(jìn)行進(jìn)一步處理,主要是對(duì)reloc段進(jìn)行修正(詳見fs/binfmt_flat.c)。 需要reloc段的根本原因是,程序在連接時(shí)連接器所假定的程序運(yùn)行空間與實(shí)際程序加載到的內(nèi)存空間不同。假如有這樣一條指令: jsr app_start; 這一條指令采用直接尋址,跳轉(zhuǎn)到app_start地址處執(zhí)行,連接程序?qū)⒃诰幾g完成是計(jì)算出app_start的實(shí)際地址(設(shè)若實(shí)際地址為0x10000),這個(gè)實(shí)際地址是根據(jù)ld文件計(jì)算出來。但實(shí)際上由于內(nèi)存分配的關(guān)系,操作系統(tǒng)在加載時(shí)無法保證程序?qū)磍d文件加載。這時(shí)如果程序仍然跳轉(zhuǎn)到絕對(duì)地址0x10000處執(zhí)行,通常情況這是不正確的。
?? 一個(gè)解決辦法是增加一個(gè)存儲(chǔ)空間,用于存儲(chǔ)app_start的實(shí)際地址,設(shè)若使用變量addr表示這個(gè)存儲(chǔ)空間。則以上這句程序?qū)⒏臑椋?movl addr, a0;??? jsr (a0); 增加的變量addr將在數(shù)據(jù)段中占用一個(gè)4字節(jié)的空間,連接器將app_start的絕對(duì)地址存儲(chǔ)到該變量。在可執(zhí)行文件加載時(shí),可執(zhí)行文件加載器根據(jù)程序?qū)⒁虞d的內(nèi)存空間計(jì)算出app_start在內(nèi)存中的實(shí)際位置,寫入addr變量。系統(tǒng)在實(shí)際處理是不需要知道這個(gè)變量的確切存儲(chǔ)位置(也不可能知道),系統(tǒng)只要對(duì)整個(gè)reloc段進(jìn)行處理就可以了(reloc段有標(biāo)識(shí),系統(tǒng)可以讀出來)。處理很簡(jiǎn)單只需要對(duì)reloc段中存儲(chǔ)的值統(tǒng)一加上一個(gè)偏置(如果加載的空間比預(yù)想的要靠前,實(shí)際上是減去一個(gè)偏移量)。偏置由實(shí)際的物理地址起始值同ld文件指定的地址起始值相減計(jì)算出。
標(biāo)準(zhǔn)Linux 的多進(jìn)程管理
??? fork創(chuàng)建的進(jìn)程幾乎是父進(jìn)程的精確復(fù)制,從fork返回后,父子進(jìn)程執(zhí)行同樣的程序,有同樣的數(shù)據(jù)和堆棧區(qū),并從緊跟fork后的指令繼續(xù)執(zhí)行。
???? exec系統(tǒng)調(diào)用提供一個(gè)進(jìn)程去執(zhí)行另一個(gè)進(jìn)程的能力,exec系統(tǒng)調(diào)用是采用覆蓋舊有進(jìn)程存儲(chǔ)器內(nèi)容的方式,所以原來程序的堆棧、數(shù)據(jù)段與程序段都會(huì)被修改。 fork的優(yōu)化:
??? (1)COW (寫時(shí)拷貝),首先由System V使用。不進(jìn)行頁(yè)面復(fù)制,父子進(jìn)程共享頁(yè)面,頁(yè)面置為只讀,無論父進(jìn)程還是子進(jìn)程試圖修改頁(yè)時(shí),發(fā)生頁(yè)失效,頁(yè)失效處理程序進(jìn)行頁(yè)面復(fù)制,并清除只讀標(biāo)志。
??? (2)BSD采用的vfork,多數(shù)程序調(diào)用完成fork后會(huì)馬上執(zhí)行exec,因此vfork不進(jìn)行頁(yè)面復(fù)制,父進(jìn)程將地址空間租界給子進(jìn)程,并將自己阻塞,直到子進(jìn)程將地址空間還給它。因此,子進(jìn)程會(huì)一直使用父進(jìn)程的地址空間直到它調(diào)用exec或exit,內(nèi)核再將地址空間返回給父進(jìn)程并喚醒它。fork非???,甚至無需拷貝頁(yè)表。它允許一個(gè)進(jìn)程使用修改另一進(jìn)程的地址空間。
?? uClinux NOMMU 但支持多進(jìn)程
?? MMU不是支持多進(jìn)程的必要條件,只是更好的支持了多進(jìn)程操作系統(tǒng)的實(shí)現(xiàn)。
?? uClinux沒有MMU管理存儲(chǔ)器,不支持COW的機(jī)制,因此fork 的優(yōu)化只有采用vfork這一途徑,并且由于不支持虛擬地址空間,簡(jiǎn)單復(fù)制的fork實(shí)現(xiàn)也必須修正reloc段。 最終,uClinux的fork/vfork都用vfork實(shí)現(xiàn)。子進(jìn)程要么代替父進(jìn)程執(zhí)行(此時(shí)父進(jìn)程已經(jīng)sleep)直到子進(jìn)程調(diào)用exit退出,要么調(diào)用exec執(zhí)行一個(gè)新的進(jìn)程,這個(gè)時(shí)候?qū)a(chǎn)生可執(zhí)行文件的加載,即使這個(gè)進(jìn)程只是父進(jìn)程的拷貝,這個(gè)過程也不能避免。當(dāng)子進(jìn)程執(zhí)行exit或exec后,子進(jìn)程使用wakeup把父進(jìn)程喚醒,父進(jìn)程繼續(xù)往下執(zhí)行。
??? 經(jīng)過如上各方面的小型化改造,就形成了一個(gè)高度優(yōu)化的、代碼緊湊的嵌入式Linux,雖然它的體積很小,uCLinux仍然保留了Linux的大多數(shù)的優(yōu)點(diǎn):穩(wěn)定、良好的移植性、優(yōu)秀的網(wǎng)絡(luò)功能、完備的對(duì)各種文件系統(tǒng)的支持、以及標(biāo)準(zhǔn)豐富的API。它的主要特征如下: ●通用Linux API ●內(nèi)核體積 < 512 KB ●內(nèi)核 +文件系統(tǒng)<900 KB ●完整的TCP/IP 協(xié)議棧 ●支持大量其它的網(wǎng)絡(luò)協(xié)議 ●支持各種文件系統(tǒng),包括 NFS、ext2、ROMfs and JFFS、MS-DOS和FAT16/32
?uClinux開發(fā)環(huán)境
基于uCLinux的應(yīng)用開發(fā)環(huán)境一般是由目標(biāo)系統(tǒng)硬件開發(fā)板和宿主PC機(jī)所構(gòu)成。硬件開發(fā)板用于操作系統(tǒng)和目標(biāo)系統(tǒng)應(yīng)用軟件的運(yùn)行,而操作系統(tǒng)內(nèi)核的編譯、應(yīng)用軟件的開發(fā)和調(diào)試則需要借助宿主PC機(jī)來完成。雙方之間一般通過串口建立連接關(guān)系。 建立交叉開發(fā)環(huán)境 在軟件開發(fā)環(huán)境建立方面,由于uCLinux及相關(guān)工具集都是開放源碼的項(xiàng)目,所以大多數(shù)軟件都可以從網(wǎng)絡(luò)上下載獲得。首先要在宿主機(jī)上安裝標(biāo)準(zhǔn)Linux發(fā)行版,比如Red-Hat Linux,接下來就可以建立交叉開發(fā)環(huán)境。 1.安裝交叉編譯工具 針對(duì)uCLinux目前有兩套編譯工具:m68k-coff和m68k-elf,它們都是GNU組織開發(fā)的優(yōu)秀的編譯器GCC的不同應(yīng)用版本。它們的區(qū)別在于形成最終flat目標(biāo)碼之前的中間代碼格式分別是coff和elf類型。elf格式的編譯器比coff格式的編譯器有許多優(yōu)越性,建議使用m68k-elf交叉編譯器。編譯工具包中除了交叉編譯器以外,還有鏈接器(ld)、匯編器(as)以及一些為了方便開發(fā)的二進(jìn)制處理工具,包括生成靜態(tài)庫(kù)工具(ar、ranlib)、二進(jìn)制碼察看工具(nm、size)、二進(jìn)制格式轉(zhuǎn)換工具(objcopy)。這些都要安裝在宿主機(jī)上。
????????? 2.安裝uCLinux內(nèi)核 利用已安裝的交叉編譯器編譯生成運(yùn)行與目標(biāo)機(jī)上的uCLinux內(nèi)核。與標(biāo)準(zhǔn)Linux相同的是,uCLinux內(nèi)核可以以配置的方式選擇需要安裝的模塊,而增加系統(tǒng)的靈活性。 3.安裝應(yīng)用程序庫(kù) 用交叉編譯器編譯uC-libc和uC-libm源碼,生成libc.a應(yīng)用程序庫(kù)和libm.a數(shù)學(xué)庫(kù)。 4.安裝其他工具 用GCC編譯elf2flt源碼,生成格式轉(zhuǎn)換工具elf2flt。用GCC編譯genromfs源碼,得到生成romfs工具genromfs。 經(jīng)過以上的準(zhǔn)備工作之后,下面要針對(duì)特定應(yīng)用所需要的設(shè)備編寫或改造設(shè)備驅(qū)動(dòng)程序。有一些設(shè)備驅(qū)動(dòng),uCLinux本身就已經(jīng)具有。即便沒有,因?yàn)閡CLinux開放源碼的特性,用戶也可以很方便地把自己的驅(qū)動(dòng)程序加入內(nèi)核。如果用戶對(duì)系統(tǒng)實(shí)時(shí)性,特別是硬實(shí)時(shí)有特殊的要求,uCLinux可以加入RT-Linux的實(shí)時(shí)模塊。完成這些工作,一個(gè)嵌入式應(yīng)用開發(fā)平臺(tái)就已經(jīng)搭建好了,在此之上,根據(jù)不同需要可以開發(fā)不同的嵌入式應(yīng)用。
評(píng)論