嵌入式Linux的技術(shù)分析
PC硬件使用的增加是近年來(lái)高端嵌入式系統的一個(gè)最重要的發(fā)展。由于這個(gè)趨勢,嵌入式系統的硬件成本大大地下降了,然而應用于嵌入式PC平臺的軟件系統卻沒(méi)有太多的選擇。
本文引用地址:http://dyxdggzs.com/article/235351.htmlinux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)
目前嵌入式操作系統主要有Palm OS,WindowsCE,EPOC,LinuxCE,QNX.ECOS,LYNX等,但這些系統一般都價(jià)格昂貴、不具有良好的可移植性。由于linux具有適應于多種CPU和多種硬件平臺、性能穩定、裁剪性能好,開(kāi)發(fā)和使用都很容易等特點(diǎn),越來(lái)越多的人傾向于將Linux嵌入到移動(dòng)計算平臺、信息家電、媒體手機及其它產(chǎn)品中去。這同時(shí)也對Linux的實(shí)時(shí)性提出了更高的要求。
我們參加開(kāi)發(fā)的上海數字技術(shù)中心的電子警察系統就是這樣一個(gè)基于PC平臺的嵌入式系統。它的主要功能是安裝在十字路口上監視闖紅燈的汽車(chē),錄制這些鏡頭,并適時(shí)通過(guò)網(wǎng)絡(luò )傳回總監控中心。該系統原來(lái)采用Vxworks作為運作平臺,然而由于Vxworks的昂貴,且只能安裝一臺機器,因此將Linux改制成嵌入式的、具有一定實(shí)時(shí)性的系統平臺。
1 硬件需求
考慮到實(shí)際的系統功能和系統開(kāi)發(fā)的難度,我們決定選擇X86體系作為平臺,底板采PCM-5864/L板,CPU選擇Intel的P55C系列,同時(shí)它也支持PC104接口。I/O方面,PCM-5864/L支持EIDE、FDD、Keyboard、Mouse、RS-232、USB等接口,同時(shí)也集成了10Mbps/l00Mbps網(wǎng)卡。另外PCM-5864/L還集成了顯卡,并提供36位TTL的LCD接口、LVDS接口和Video-in/TV-out接口。由于電子磁盤(pán)體積小、抗震性能也較好的特點(diǎn),我們選用M-Systems公司的DiskOnChip2000作為存儲設備,這樣比較適合該系統戶(hù)外作業(yè)的特性。Doc2000還提供了安裝的工具包、Linux下的驅動(dòng)程序和對不同版本Linux內核的Patch。安裝時(shí)只需對Linux內核和Lilo進(jìn)行相應修改即可。這樣的硬件選擇使系統開(kāi)發(fā)的難度大大降低了。
2 嵌入Linux主要解決的幾個(gè)問(wèn)題
由于采用X86體系作為平臺,大大降低了嵌入化Linux的難度,主要要考慮的問(wèn)題可分為以下幾個(gè)方面:
2.1 非虛擬內存
Linux采用虛擬內存技術(shù),當數據溢出內存時(shí),可以將其交換到磁盤(pán)交換空間巾去,這對程序員來(lái)說(shuō)是不可見(jiàn)的。然而,普通的嵌入式系統不需要這種強大的功能。實(shí)際上,可能不希望它在實(shí)時(shí)的關(guān)鍵系統里,因為它會(huì )帶來(lái)無(wú)法控制的時(shí)問(wèn)因素。因此,考慮將虛擬內存的功能去掉。然而,清除Linux的虛擬內存代碼非常費事,我們采用一種迂回的方法,即將交換空間的大小設置為零。這樣,如果你寫(xiě)的程序比實(shí)際的內存大,系統就會(huì )當作你的運行用盡了交換空間來(lái)處理;這個(gè)程序將不會(huì )運行,或者malloc將會(huì )失靈。這只是一種臨時(shí)的解決方案,系統中存在許多冗余未清除的代碼,如果進(jìn)一步改進(jìn)可以縮小系統體積。
2.2 處理文件系統
許多嵌入式系統沒(méi)有磁盤(pán)或者文件系統,Linux不需要它們也能運行,這樣可以在系統啟動(dòng)時(shí)就將操作系統和預先編好的應用程序全都加載到內存中去。然而.考慮到以后的擴展,我們分析了Linux當前的文件系統,將與系統和程序運行相關(guān)的文件析取出來(lái),移植到Doc上面.這樣就能為應用程序的開(kāi)發(fā)人員提供更方便的接口。
2.3 設置啟動(dòng)(Lilo和BIOS)
當PC系統啟動(dòng)時(shí),由BIOS執行了一些低水平的CPU初始化和其它硬件的配置,然后辨認哪個(gè)磁盤(pán)里有操作系統,把操作系統復制到RAM并且轉向它。在PC上運行的Linux依靠PC的BIOS來(lái)提供這些配置和OS加戟功能。由于選擇了X86系列作為平臺,同樣可以通過(guò)設置BIOS來(lái)設定由Doc啟動(dòng)。我們將內核安裝在Doc上。同時(shí)修改目錄/etc下的lilo.config文件,使Lilo記錄內核代碼在存儲設備上的位置,然后將Lilo安裝在Doc上。這樣當系統啟動(dòng)時(shí).BIOS指定Doc為啟動(dòng)設備,這時(shí)Lilo被執行。它指出Linux內核的位置,加載內核。
2.4 設備驅動(dòng)程序的編寫(xiě)
由于采用通用PC平臺,有許多驅動(dòng)程序都不需要自己再編寫(xiě)了。系統中,唯一需要編寫(xiě)驅動(dòng)程序的設備是上海數字中心的數據采集卡.該卡采用的是Bt848芯片。Bt848是一塊很常用的芯片.許多驅動(dòng)程序都非常相近,因此編寫(xiě)它的驅動(dòng)程序有很好的例子可以參考,相應的,編寫(xiě)應用程序只需調用驅動(dòng)程序提供的接口即可,如同操作文件一樣。
3 Linux的實(shí)時(shí)性分析
以上簡(jiǎn)要介紹了實(shí)現Linux的嵌入化過(guò)程,在嵌入化Linux的同時(shí),還考慮提高它的實(shí)時(shí)性。于是著(zhù)手分析Linux的實(shí)時(shí)性能和存在的不足。
概括來(lái)講,影響操作系統實(shí)時(shí)性能的主要有3個(gè)方面:
(1)外部中斷管理
我們知道,外部中斷發(fā)生時(shí),操作系統調用中斷處理程序.進(jìn)入核心態(tài)。為了保證系統執行的正確性,要求內核狀態(tài)不重入,也即保證這部分關(guān)鍵代碼執行結束之前不被打斷。因此,這時(shí)進(jìn)入關(guān)中模式,這是外部中斷管理中影響Linux性能的一個(gè)關(guān)鍵的地方。在這段時(shí)間內,操作系統負責將中斷發(fā)送到相應的設備驅動(dòng)程序去處理,系統不能進(jìn)行其它任何工作,為了減少這個(gè)過(guò)程損耗的時(shí)間,Linux內核利用底半處理過(guò)程(bottom-half-handler)幫助實(shí)現中斷的快速處理。在Linux設備驅動(dòng)程序中,往往將最關(guān)鍵最迅速的部分處理完成之后,將剩余部分任務(wù)放置到隊列中。當中斷響應完成后.再執行剩余部分的任務(wù)。在Linux中,主要設置了以下幾個(gè)數據結構來(lái)標志未完成的任務(wù)。
enum{
TIMER_BH=0,CONSOLE_BH,TQUEUE_BH,DIGI_BH,SERIAL_BH,RISCOM8_BH,SPECIALIX_BH,
ESP_BH,NET_BH,SCSI_BH,IMMEDIATE_BH,KEYBOARD_BH,CYCLADES_BH,CM206_BH,
JS_BH,MACSERIAL_BHISICOM_BH
};
上面每一項標識未完成任務(wù)的隊列類(lèi)型,不同隊列的任務(wù)輕重緩急不同。
extern unsigned long bh_active;
extern unsigned long bh_mask;
extern void(*bh_base[32])(void);
bh_base代表的指針數組中可包含32個(gè)不同的底半處理過(guò)程。bh_mask和札bh_active的數據位分別代表對應的底半處理過(guò)程是否安裝和激活。如果bh_mask的第N位為1.則說(shuō)明bh_base數組的第N個(gè)元素包含某個(gè)底半處理過(guò)程的地址;如果bh_active的第N位為1.則說(shuō)明必須由調度程序在適當的時(shí)候調用第N個(gè)底半處理過(guò)程。這些數據結構的設置一般是在外部設備初始化和中斷處理函數運行時(shí)進(jìn)行的。如:在serialc中進(jìn)行serial設備的初始化,它調用語(yǔ)句init_bh(SERIAL_BH,do_serial_bh);來(lái)設置bh_base[]數組中相應于SERIAL_BH的那一項。又如:在serial設備的處理程序中通過(guò)語(yǔ)句queue_task(&info->tqueue,&tq_serial);將不是很緊急的任務(wù)放入tq_serial隊列中,等中斷處理函數結束,由bh_base中注冊的底半處理程序處理隊列中的任務(wù)。
中斷管理的第二個(gè)關(guān)鍵部分即是系統是否允許中斷嵌套的能力,也就是說(shuō),當響應一個(gè)中斷時(shí),是否允許其它更高優(yōu)先級的中斷打斷,等更高優(yōu)先級的中斷處理完畢,是否還能恢復原來(lái)中斷處理的現場(chǎng)。通過(guò)這項功能,系統設計者可以指示外部中斷的優(yōu)先級,從而確保高優(yōu)先級的任務(wù)能及時(shí)處理。Linux允許中斷嵌套,它是利用外部中斷管理器來(lái)設置中斷的優(yōu)先級的。在Linux的中斷處理程序的啟動(dòng)過(guò)程中,它一般調用語(yǔ)句mask_and_ack_8259A(irq);來(lái)設置8259中的int_mask寄存器.使優(yōu)先級比此中斷低的中斷不能發(fā)生。在中斷處理程序離開(kāi)時(shí),調用enable_8259A_irq(irq)來(lái)改回8259中int_mask寄存器原來(lái)的值。因此,intr類(lèi)中斷的優(yōu)先級由硬件8259來(lái)決定.
由此可見(jiàn),Linux的中斷管理部分具有高效的特點(diǎn),已經(jīng)可以滿(mǎn)足許多軟實(shí)時(shí)任務(wù)的要求。
(2)進(jìn)程搶先調度
在許多控制系統中,實(shí)時(shí)控制軟件是非常簡(jiǎn)單的,可以直接寫(xiě)入中斷處理程序中與一個(gè)特定的中斷聯(lián)系起來(lái)。還有一些就不那么簡(jiǎn)單了,必須開(kāi)啟專(zhuān)門(mén)的用戶(hù)進(jìn)程為它服務(wù)。
這時(shí)當這個(gè)高優(yōu)先級的進(jìn)程提交時(shí),如有其它進(jìn)程正在運行,它就必須打斷正在運行的進(jìn)程。若正在運行的進(jìn)程運行在用戶(hù)態(tài),系統一般允許它被打斷且執行其它優(yōu)先權高的進(jìn)程,若正在運行的進(jìn)程運行在系統態(tài),則此時(shí)是否允許被打斷決定了系統是搶先式的還是非搶先式的。
Linux就是一個(gè)非搶先式的操作系統,在用戶(hù)執行系統調用時(shí),不允許其它進(jìn)程的調度,這樣就影響了系統的響應度。一個(gè)真正的搶先式的操作系統允許正在系統狀態(tài)下的當前進(jìn)程被打斷,然后進(jìn)程切換回來(lái)時(shí)還能繼續從剛才的執行點(diǎn)繼續下去。但某些關(guān)鍵部分的代碼段。系統必須保證其原子性,并防止重入。通常有如下幾種方法:
在關(guān)鍵代碼斷前關(guān)閉中斷,等其執行完畢之后再將中斷打開(kāi); 設計一個(gè)信號量.在關(guān)鍵代碼段之前加鎖,在其后解鎖;
在系統代碼中保證安全的地方加入切換進(jìn)程的代碼switch(),防止該進(jìn)程長(cháng)久占用CPU,允許調度其它進(jìn)程; 在關(guān)鍵代碼段加入一個(gè)switchaccept標志,開(kāi)始該代碼段時(shí)。將此標志置為否.離開(kāi)時(shí)再置回原來(lái)的值.這樣在執行該段代碼時(shí),即使進(jìn)程調度器被激活,它也會(huì )先檢查此標志。若為否,則返回,并不進(jìn)行進(jìn)程切換。
(3)進(jìn)程調度策略
第三個(gè)影響系統響應速度的關(guān)鍵部分就是進(jìn)程調度的策略。對于一個(gè)實(shí)時(shí)性能強的操作系統來(lái)說(shuō),系統必須規定不同進(jìn)程的優(yōu)先級,并把優(yōu)先級作為唯一的進(jìn)程選擇的標準。Linux的后期版本參照Posixl.b標準,在某些方面已經(jīng)具備了一些實(shí)時(shí)操作系統的特性。Linux有兩種類(lèi)型的進(jìn)程:一般進(jìn)程和實(shí)時(shí)進(jìn)程,它可以通過(guò)sched_setscheduler系統調用設置實(shí)時(shí)進(jìn)程。實(shí)時(shí)進(jìn)程比所有一般進(jìn)程的優(yōu)先級高,Linux設置實(shí)對進(jìn)程的權重為它的counter值加1000;設置一般進(jìn)程的權重為counter。因此,實(shí)時(shí)進(jìn)程總會(huì )被認為是最值得運行的進(jìn)程。
然而,Linux核心的設計主要集中在應用程序的吞吐量上。追求吞吐量的必然結果,就是Linux調度器運用一種"公平共享"的策略保證所有的進(jìn)程得到平均的CPU資源。而且,Linux的進(jìn)程調度器只是簡(jiǎn)單地將標有實(shí)時(shí)標志的進(jìn)程的權重加1000,至于實(shí)時(shí)進(jìn)程間的輕重緩急還沒(méi)有周密的完整的設計。因此,Linux的進(jìn)程調度器還遠不能稱(chēng)作是一個(gè)真正的實(shí)時(shí)進(jìn)程凋度器。
4 擬采用的策略
根據以上分析的特點(diǎn),我們決定主要從以下4個(gè)方面來(lái)修改Linux的核心代碼。
(1)在內核中插入搶先點(diǎn) 由于Linux是一個(gè)非搶先式的操作系統。因此當一個(gè)實(shí)時(shí)進(jìn)程提交時(shí),很可能因為當前的進(jìn)程正處于核心態(tài)不能被打斷而不能得到及時(shí)的處理。因此有必要在Linux內核中插入搶先點(diǎn),使實(shí)時(shí)進(jìn)程得到處理。根據上一節分析的特點(diǎn),太體有4種方法可供選擇。權衡這4種方法的利弊,我們決定采用第4種方法,即在關(guān)鍵代碼段加入一個(gè)switchaccept標志,開(kāi)始該代碼段時(shí),將此標志置為否.離開(kāi)時(shí)再置回原來(lái)的值。這種方法比采甩semaphore的好處是,如果采用許多種semaphore的話(huà).要考慮是否會(huì )產(chǎn)生死鎖的問(wèn)題。比采用鎖中斷的好處是.將中斷鎖住將丟失中斷,而這樣不會(huì )。而以固定的周期加switch語(yǔ)句顯然有失靈活性。這樣.采用這種方法,需要我們分析Linux所有系統調用的代碼,畫(huà)出其結構流程圖。分析出哪些部分是關(guān)鍵部分,也即不允許置入的部分。在關(guān)鍵代碼前后更改switchaccept標志。這項工作比較艱巨。同時(shí)修改進(jìn)程調度器,使其判斷switchaccept標志來(lái)決定是否執行進(jìn)程切換。
(2)修改進(jìn)程調度器Linux的進(jìn)程調度器雖然已經(jīng)具有一定的實(shí)時(shí)性能,但還遠遠達不到真正實(shí)時(shí)調度器的標準,因此需要修改其進(jìn)程調度器,必要的話(huà)可讓Linux運行在兩種模式下,實(shí)時(shí)模式和分時(shí)模式??稍O計一些相關(guān)的系統調用,并在實(shí)時(shí)進(jìn)程提交時(shí),將系統轉化為實(shí)時(shí)模式,當實(shí)時(shí)進(jìn)程結束時(shí),再轉化為分時(shí)模式。
(3)Linux的中斷管理根據前面分析過(guò)的,Linux的中斷管理及時(shí)地將緊要的任務(wù)完成后,將其余不重要的緩慢的任務(wù)放置在任務(wù)隊列中,等到系統空閑(cpu idle())或系統調用等返回時(shí)再完成這些任務(wù),這樣就提高了系統的響應速度,同時(shí),Linux還支持中斷嵌套。因此,不再對其作太大改動(dòng)。
(4)鎖定內存 在本項目的規劃中本打算實(shí)現Linux鎖內存的功能,使優(yōu)先權高的進(jìn)程在內存中的數據不被換出,從而提高實(shí)時(shí)進(jìn)程的運行速度。然而,在分析了Linux代碼后,發(fā)現后來(lái)版本的Linux已通過(guò)系統調用sys mlock實(shí)現了此項功能。
5 結束語(yǔ)
采用上述方法修改了內核代碼后,由于每個(gè)修改方案都是有一定的代價(jià)的,它在增加了系統響應速度的同時(shí)也在某種程度上降低了系統的整體效率,比如說(shuō)將內核設置成可搶先的,在進(jìn)程頻繁的切換過(guò)程中也要消耗一定的cpu處理時(shí)間。因此,還需要對各種解決方案進(jìn)行測試、比較。另外,為了減少嵌入式Linux自身的長(cháng)度,在存儲管理部分對虛擬內存也應作進(jìn)一步的處理。
linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)linux相關(guān)文章:linux教程
評論