版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
畢業(yè)設(shè)計(jì)(論文)第 PAGEII頁(yè)畢業(yè)設(shè)計(jì)(論文)設(shè)計(jì)(論文)題目:實(shí)時(shí)嵌入式操作系統(tǒng)的設(shè)計(jì)學(xué)生姓名學(xué)生學(xué)號(hào) 專業(yè)班級(jí) 指導(dǎo)老師 年5月29日實(shí)時(shí)嵌入式操作系統(tǒng)的設(shè)計(jì)摘要隨著微處理器的發(fā)展,種類繁多、價(jià)格低廉、結(jié)構(gòu)小巧的CPU和外設(shè)連接,提供了穩(wěn)定、可靠的硬件架構(gòu)?,F(xiàn)在嵌入式系統(tǒng)發(fā)展的瓶頸在軟件方面,尤其是操作系統(tǒng)的“嵌入式”化。由于Linux源碼的開放性、簡(jiǎn)練、多任務(wù)、易移植、成本低等特性,成為諸多研究與應(yīng)用選擇的對(duì)象。隨著2.6內(nèi)核的發(fā)布,Linux向現(xiàn)有主流的實(shí)時(shí)操作系統(tǒng)提出了更大的挑戰(zhàn),勢(shì)必能成為更優(yōu)秀的嵌入式操作系統(tǒng)。本人一直以來(lái)都對(duì)Linux操作系統(tǒng)很感興趣,并結(jié)合本專業(yè),對(duì)Linux應(yīng)用于嵌入式實(shí)時(shí)環(huán)境進(jìn)行了一定的研究。深入探討了面向嵌入式實(shí)時(shí)環(huán)境的Linux系統(tǒng)的體系結(jié)構(gòu)。論文首先概述了嵌入式系統(tǒng)及實(shí)時(shí)系統(tǒng)的發(fā)展情況,然后介紹Linux在實(shí)時(shí)領(lǐng)域的相關(guān)研究,其次講述了嵌入式Linux系統(tǒng)的構(gòu)造,最后描述了系統(tǒng)測(cè)試的策略,并就下一步可繼續(xù)進(jìn)行的工作進(jìn)行了展望。關(guān)鍵詞: Linux;進(jìn)程;實(shí)時(shí)系統(tǒng);嵌入式系統(tǒng)。
DesignontheKernelofEmbeddedOperatingSystemAbstractWithmicroprocessordevelopment,awiderangeoflowprice,compactstructureoftheCPUandperipheralsandprovideastable,reliablehardwarearchitecture.Embeddedsystemdevelopmentisnowthebottleneckinthesoftware,especiallyoperatingsystems,"embedded"change.Duetotheopen-sourceLinux,concise,multi-task,multi-taskandeasytotransplant,andlowcostcharacteristics,asmanyresearchandapplicationofchoicetarget.Withrelease2.6ofthekernel,Linuxtothemainstreamoftheexistingreal-timeoperatingsystemproviders,thegreaterthechallenge,isboundtobecomemoreoutstandingEmbeddedoperatingsystem.IgotinterestwithLinuxoperatingsystemseveralyearsago.Combinationmyspecialty,ThenIdidsomeresearchforreal-timeLinux.Basedonthesefacts,thisthesisdemonstratesarchitectureandinternalsofLinuxsystemusedonembeddedsystems.Thepaperoutlinedthesystemsandembeddedreal-timesystemdevelopment,Thenreal-timeLinuxinthefieldofresearch,followedbyaboutembeddedLinuxsysteminthestructure,Descriptionofthefinalsystemtestingstrategies,andonthenextstepstocontinuetheworkforward.Keywords:RealTimeSystem,EmbeddedSystem,process,Linux目錄1嵌入式實(shí)時(shí)系統(tǒng)概況 11.1嵌入式系統(tǒng)概況 11.1.1關(guān)于嵌入式系統(tǒng) 11.1.2嵌入式系統(tǒng)的基本特征 21.1.3典型的嵌入式系統(tǒng) 21.2實(shí)時(shí)嵌入式系統(tǒng)概況 31.2.1什么是實(shí)時(shí)嵌入式系統(tǒng) 31.2.2實(shí)時(shí)嵌入式操作系統(tǒng) 42Linux作為實(shí)時(shí)系統(tǒng)的分析 62.1Linux內(nèi)核體系結(jié)構(gòu) 62.2Linux進(jìn)程管理 72.2.1進(jìn)程描述符 82.2.2進(jìn)程調(diào)度 132.2.2搶占 162.2.3調(diào)度器的實(shí)時(shí)性能 183構(gòu)造嵌入式Linux系統(tǒng) 203.1uClinux結(jié)局方案 203.2構(gòu)造潛入式Linux系統(tǒng) 213.2.1構(gòu)建嵌入式Linux系統(tǒng)的幾個(gè)關(guān)鍵問(wèn)題 213.2.1構(gòu)建嵌入式Linux系統(tǒng)的關(guān)鍵步驟 243.3uClinux在ARMulator的移植 254測(cè)試方案 28總結(jié) 29致謝 30參考文獻(xiàn) 311嵌入式實(shí)時(shí)系統(tǒng)概況1.1嵌入式系統(tǒng)概況1.1.1關(guān)于嵌入式系統(tǒng)嵌入式系統(tǒng)在現(xiàn)代人的日常生活中已經(jīng)無(wú)處不在(如圖1-1),而且正在越來(lái)越深地介入我們的生活、工作甚至娛樂(lè)。圖1-1日常生活中的嵌入式系統(tǒng)從幾十年前出現(xiàn)的計(jì)算機(jī)開始,人們身邊出現(xiàn)了越來(lái)越多的嵌入式系統(tǒng),而Intel公司第一款處理其4004的主要應(yīng)用就是計(jì)算器。電話是影響人們生活方式的重要發(fā)明成果之一,作為其核心設(shè)備的存儲(chǔ)程序控制(SPC)電話交換機(jī)早在上個(gè)世紀(jì)中后期就已經(jīng)出現(xiàn),電話交換機(jī)就是一類典型的實(shí)時(shí)嵌入式系統(tǒng)。除通訊、國(guó)防、航空航天和醫(yī)療領(lǐng)域以外,汽車工業(yè)也是嵌入式系統(tǒng)使用最早的行業(yè)之一。當(dāng)今的每部中高檔汽車上都至少有幾套甚至幾十套嵌入式系統(tǒng)在協(xié)調(diào)工作,控制著汽車的轉(zhuǎn)向、液壓、制動(dòng)、空調(diào)、ABS等等一系列功能,其中大多數(shù)都是實(shí)時(shí)系統(tǒng)。今年來(lái),嵌入式系統(tǒng)以消費(fèi)電子設(shè)備的形態(tài)大量進(jìn)入人們的生活:移動(dòng)電話、數(shù)碼相機(jī)、數(shù)字?jǐn)z像機(jī)、游戲機(jī)、電子辭典、PDA(PersonalDigitalAssistant,個(gè)人數(shù)字助理)、MP3播放器、微波爐、空調(diào)、數(shù)字電視、DVD播放機(jī)、傳真機(jī)等[1]。Internet是近年來(lái)對(duì)人們生活方式影響最大的技術(shù)成果。但為大多數(shù)人所忽略的是,Internet實(shí)際上是有史以來(lái)世界上最大的嵌入式系統(tǒng)集合。Internet上的高端路由器、ATM交換機(jī)、以太網(wǎng)交換機(jī)、網(wǎng)關(guān)等核心設(shè)備都是實(shí)時(shí)處理能力很強(qiáng)的嵌入式系統(tǒng)。1.1.2嵌入式系統(tǒng)的基本特征從以上那些耳熟能詳?shù)那度胧皆O(shè)備中(其中某些是實(shí)時(shí)嵌入式設(shè)備),我們應(yīng)該能感覺(jué)到嵌入式系統(tǒng)的一些基本特征:嵌入式系統(tǒng)由智能單元(即微處理器,有時(shí)存在多個(gè))控制,因而是計(jì)算機(jī)系統(tǒng)。但因形態(tài)多樣,多數(shù)情況下此特征為人們所忽略。嵌入式系統(tǒng)所提供的功能通常帶有針對(duì)性,大多是專用系統(tǒng)。與桌面系統(tǒng)不同,嵌入式系統(tǒng)一般不對(duì)用戶提供再開發(fā)環(huán)境,用戶與系統(tǒng)交互的唯一端口就是系統(tǒng)提供給用戶的最終應(yīng)用。針對(duì)某些特殊應(yīng)用,如航天飛機(jī)、衛(wèi)星、飛機(jī)等,嵌入式系統(tǒng)常常需要很高的可靠性和長(zhǎng)時(shí)間無(wú)人值守的工作能力。這一點(diǎn)對(duì)操作系統(tǒng)得要求至關(guān)重要。緊湊性要求明顯(因系統(tǒng)而異)?;诔杀?、體積、功耗和性價(jià)比等因素考慮,許多嵌入式系統(tǒng)通常不追求高速而功耗大的處理器,采用盡可能少(但夠用)的存儲(chǔ)器。他的軟件(或固件/Firmware)和數(shù)據(jù)通常保存在系統(tǒng)的非易失存儲(chǔ)器上(如Flash)。這些都對(duì)操作系統(tǒng)的處理性能和可裁減性有特殊要求。實(shí)時(shí)性需求。在給定硬件環(huán)境條件下,系統(tǒng)實(shí)時(shí)性主要依靠操作系統(tǒng)和應(yīng)用軟件保障。1.1.3典型的嵌入式系統(tǒng)信息家電商機(jī)引發(fā)全球嵌入式操作系統(tǒng)平臺(tái)大戰(zhàn),全球4大操作系統(tǒng)陣營(yíng)WinCE、PalmOS、EPOC和Linux展開規(guī)格戰(zhàn),各擁有軟件及硬件合作廠商逐鹿信息家電市場(chǎng)的份額。微軟窗口操作系統(tǒng)擁有在個(gè)人電腦上的操作系統(tǒng)占有率的優(yōu)勢(shì),使WinCE擁有強(qiáng)大的窗口資源支援。不過(guò)PalmOS操作系統(tǒng)擁有全球PDA產(chǎn)品70%的市場(chǎng)占有率;同時(shí)獲得3COM、IBM和索尼等跨國(guó)公司的支持。EPOC是發(fā)展自歐洲的操作系統(tǒng)、是由世界上最大的3家移動(dòng)電話廠商諾基亞、愛(ài)立信和摩托羅拉所共同開發(fā)、整合組成新公司,開發(fā)出來(lái)的新操作系統(tǒng);在3大電話廠商的合作下,EPOC市場(chǎng)潛力很大,且占有率高,但應(yīng)用功能以手機(jī)為主,目前并不開放授權(quán)。此外,在3大主流操作系統(tǒng)品牌外,Linux也將是今后一股強(qiáng)勁的力量;由于Linux開放源碼,經(jīng)過(guò)這些年的發(fā)展,已經(jīng)成為一個(gè)健壯的可靠的高性能的操作系統(tǒng)。愈來(lái)愈多的嵌入式系統(tǒng)設(shè)計(jì)員發(fā)現(xiàn)Linux可以成為一個(gè)優(yōu)秀的嵌入式操作系統(tǒng)。而Linux的最大的優(yōu)勢(shì)還在于它是一個(gè)開放的操作系統(tǒng)。由于Linux開放源碼,操作系統(tǒng)的一切對(duì)用戶都是透明的,用戶可以最大限度地控制系統(tǒng)開發(fā)的進(jìn)度和造價(jià)。在開發(fā)過(guò)程中遇到的各種各樣的硬件設(shè)備,可以方便地在網(wǎng)上找到這些設(shè)備的驅(qū)動(dòng)程序,得到支持。Linux內(nèi)置網(wǎng)絡(luò)支持,用戶可以輕松地使自己的嵌入式具有網(wǎng)絡(luò)功能。Linux是模塊化的操作系統(tǒng),提供了優(yōu)秀的可縮放功能,用戶可以方便地刪除不需要的模塊,大多數(shù)嵌入式系統(tǒng)對(duì)操作系統(tǒng)的體積非常敏感,Linux的可以根據(jù)自己的需要,選擇特定的功能模塊,自主地搭建嵌入式操作系統(tǒng)。Linux支持絕大多數(shù)CPU,包括Intel、MIPS、ASIC、ALPHA、68K、POWERPC等。這使Linux幾乎可以嵌入到各種硬件設(shè)備上。成為各家廠商極力發(fā)展的操作系統(tǒng),加上其核心小,潛力可觀。1.2實(shí)時(shí)嵌入式系統(tǒng)概況1.2.1什么是實(shí)時(shí)嵌入式系統(tǒng)嵌入式系統(tǒng)不都是實(shí)時(shí)系統(tǒng)。比如掌上電腦、電子辭典等,它們具備嵌入式系統(tǒng)的基本特征,但基本沒(méi)有實(shí)時(shí)性要求。而實(shí)時(shí)性系統(tǒng)也不都是嵌入式系統(tǒng)。當(dāng)我們將個(gè)人電腦裝上實(shí)時(shí)操作系統(tǒng)并用于工業(yè)生產(chǎn)線實(shí)時(shí)控制時(shí),該系統(tǒng)并不具備被嵌入式特征,因此我們可以說(shuō)實(shí)時(shí)嵌入式系統(tǒng)是嵌入式系統(tǒng)與實(shí)時(shí)系統(tǒng)的交集(如圖1-2)。但一般而言,嵌入式系統(tǒng)中有相當(dāng)大的比例是實(shí)時(shí)系統(tǒng)。[2]圖1-2嵌入式實(shí)時(shí)系統(tǒng)的邊界與非實(shí)時(shí)系統(tǒng)不同之處在于,實(shí)時(shí)系統(tǒng)對(duì)外部事件的響應(yīng)有時(shí)間要求,即要在給定時(shí)間內(nèi)完成事件的識(shí)別、處理,并給出正確結(jié)果。外部事件可分為兩類,即同步時(shí)間(SynchronousEvents)和異步事件(AsynchronousEvents)。同步事件是周期性的,系統(tǒng)可以預(yù)見下一次同類事件發(fā)生的時(shí)刻;異步事件是非周期的,事件發(fā)生的事件不可預(yù)測(cè)。實(shí)時(shí)操作系統(tǒng)必須有能力處理這兩類事件。Deadline是實(shí)時(shí)系統(tǒng)追求的最重要的指標(biāo)。但不同的實(shí)時(shí)系統(tǒng)得Deadline的要求不同,并據(jù)此將實(shí)時(shí)系統(tǒng)分為兩類:HardReal-time(硬實(shí)時(shí))和SoftReal-time(軟實(shí)時(shí))。1.2.2實(shí)時(shí)嵌入式操作系統(tǒng)同樣作為操作系統(tǒng),實(shí)時(shí)嵌入式操作系統(tǒng)與通常意義上的操作系統(tǒng)在基本功能方面應(yīng)該是一致的,但必然存在明顯差異。首先,實(shí)時(shí)嵌入式操作系統(tǒng)負(fù)責(zé)實(shí)時(shí)嵌入式系統(tǒng)的所有軟硬件資源的分配、調(diào)度工作、控制和協(xié)調(diào)并發(fā)活動(dòng),如任務(wù)調(diào)度、內(nèi)存管理、同步機(jī)制、異常和中段處理、任務(wù)間通信等,具有一般操作系統(tǒng)的基本功能:同時(shí)它也必須具有其實(shí)時(shí)處理和嵌入式系統(tǒng)特征。與通用操作系統(tǒng)相比,實(shí)時(shí)嵌入式操作系統(tǒng)具有如下一些特點(diǎn)[3]:實(shí)時(shí)性。大多數(shù)嵌入式系統(tǒng)工作在實(shí)時(shí)性要求很高的環(huán)境中,對(duì)外部事件的響應(yīng),包括數(shù)據(jù)的獲取、處理和數(shù)據(jù)的輸出都必須在deadline規(guī)定時(shí)間內(nèi)完成。這就要求實(shí)時(shí)嵌入式操作系統(tǒng)必須將實(shí)時(shí)性作為一個(gè)重要指標(biāo)。小型化、可裁減。嵌入式系統(tǒng)所能提供的資源有限,所以實(shí)時(shí)嵌入式操作系統(tǒng)必須做得小巧,以滿足前入式系統(tǒng)的硬件限制,同時(shí)必須能夠根據(jù)應(yīng)用的要求進(jìn)行裁減,去除多余的部分,或者簡(jiǎn)化相應(yīng)得模塊。強(qiáng)穩(wěn)定性。與桌面系統(tǒng)不同,大多數(shù)嵌入式系統(tǒng)一旦開始運(yùn)行就不需要人過(guò)多的干預(yù)。在這種條件下,要求作為系統(tǒng)資源總管的操作系統(tǒng)具有較高的穩(wěn)定性。固化代碼。在嵌入式系統(tǒng)中,操作系統(tǒng)與應(yīng)用軟件代碼通常被固化在嵌入式系統(tǒng)的ROM中。目前輔助存儲(chǔ)器(如磁盤)在嵌入式系統(tǒng)中很少使用,因此,實(shí)時(shí)嵌入式操作系統(tǒng)的文件管理功能應(yīng)該能夠很容易裁減,取而代之的是各種內(nèi)存文件系統(tǒng)。弱交互性。除消費(fèi)類電子設(shè)備以外,大多數(shù)嵌入式系統(tǒng)的工作過(guò)程不需要人的干預(yù)。因此多數(shù)實(shí)時(shí)嵌入式操作系統(tǒng)所提供給用戶操作的接口相對(duì)簡(jiǎn)單,主要通過(guò)系統(tǒng)調(diào)用命令向用戶程序提供服務(wù)。專業(yè)化強(qiáng)。每一種實(shí)時(shí)嵌入式操作系統(tǒng)通常面向特定類型或幾種相近類型應(yīng)用。某些操作系統(tǒng)會(huì)根據(jù)不同的應(yīng)用對(duì)象采用不同的模塊搭配。有些操作系統(tǒng)甚至是自行研發(fā)的內(nèi)部產(chǎn)品。值得注意的是,隨著各種各樣的實(shí)時(shí)嵌入式操作系統(tǒng)的出現(xiàn),人們有必要對(duì)實(shí)時(shí)嵌入式系統(tǒng)提供的借口進(jìn)行約定,從而為嵌入式應(yīng)用軟件的設(shè)計(jì)者提供統(tǒng)一的服務(wù)借口,例如POSIX(PortableOperationSystemInterface,可移植操作系統(tǒng)接口)有可移植性和平臺(tái)無(wú)關(guān)性。[4]通過(guò)上面的敘述,我們知道實(shí)時(shí)性能使評(píng)價(jià)實(shí)時(shí)嵌入式操作系統(tǒng)的重要指標(biāo),但不是唯一的指標(biāo)。完善的操作系統(tǒng)應(yīng)提供完善的功能和豐富的開發(fā)工具,如文件管理、設(shè)備支持、網(wǎng)絡(luò)支持、人機(jī)交互、GUI、API豐富度、硬件無(wú)關(guān)設(shè)計(jì),以及編譯環(huán)境、調(diào)試環(huán)境、多種處理器支持、穩(wěn)定度、可裁減性、可擴(kuò)充性、開放接口以及維護(hù)等諸多方面。而Linux操作系統(tǒng)在這些方面都有相當(dāng)出色的表現(xiàn)。2Linux作為實(shí)時(shí)系統(tǒng)的分析Linux可以說(shuō)是世界上變化最快的操作系統(tǒng),幾乎每個(gè)月都會(huì)有新的內(nèi)核升級(jí)版本問(wèn)世,這也是Linux進(jìn)步如此神速的主要原因。根據(jù)功能不同,Linux內(nèi)核的模塊可基本劃分為進(jìn)程管理、內(nèi)存管理、網(wǎng)絡(luò)管理、文件系統(tǒng)與進(jìn)程通信幾部分。實(shí)時(shí)可靠性是嵌入式應(yīng)用較為普遍的要求,盡管Linux已發(fā)展到2.6版本,但它仍不是一個(gè)真正的實(shí)時(shí)操作系統(tǒng),但其改進(jìn)的特性能夠滿足響應(yīng)需求。Linux2.6已經(jīng)在內(nèi)核主體中加入了提高中斷性能和調(diào)度響應(yīng)時(shí)間的改進(jìn),其中有三個(gè)最顯著的改進(jìn):采用可搶占內(nèi)核、更加有效的調(diào)度算法以及同步性的提高[5]。2.1Linux內(nèi)核體系結(jié)構(gòu)Linux內(nèi)核主要由五個(gè)子系統(tǒng)組成:進(jìn)程調(diào)度,內(nèi)存管理,虛擬文件系統(tǒng),網(wǎng)絡(luò)接口,進(jìn)程間通信。[6]1進(jìn)程調(diào)度(SCHED):控制進(jìn)程對(duì)CPU的訪問(wèn)。當(dāng)需要選擇下一個(gè)進(jìn)程運(yùn)行時(shí),由調(diào)度程序選擇最值得運(yùn)行的進(jìn)程。可運(yùn)行進(jìn)程實(shí)際上是僅等待CPU資源的進(jìn)程,如果某個(gè)進(jìn)程在等待其它資源,則該進(jìn)程是不可運(yùn)行進(jìn)程。Linux使用了比較簡(jiǎn)單的基于優(yōu)先級(jí)的進(jìn)程調(diào)度算法選擇新的進(jìn)程。2內(nèi)存管理(MM)允許多個(gè)進(jìn)程安全的共享主內(nèi)存區(qū)域。Linux的內(nèi)存管理支持虛擬內(nèi)存,即在計(jì)算機(jī)中運(yùn)行的程序,其代碼,數(shù)據(jù),堆棧的總量可以超過(guò)實(shí)際內(nèi)存的大小,只是把當(dāng)前使用的程序塊保留在內(nèi)存中,其余的程序塊則保留在中。必要時(shí),操作系統(tǒng)負(fù)責(zé)在磁盤和內(nèi)存間交換程序塊。內(nèi)存管理從邏輯上分為無(wú)關(guān)部分和硬件有關(guān)部分。硬件無(wú)關(guān)部分提供了進(jìn)程的映射和邏輯內(nèi)存的對(duì)換;硬件相關(guān)的部分為內(nèi)存管理硬件提供了虛擬接口[10]。3虛擬文件系統(tǒng)(VirtualFileSystem,VFS)隱藏了各種硬件的具體細(xì)節(jié),為所有的設(shè)備提供了統(tǒng)一的接口,VFS提供了多達(dá)數(shù)十種不同的文件系統(tǒng)。虛擬文件系統(tǒng)可以分為邏輯文件系統(tǒng)和設(shè)備程序。邏輯文件系統(tǒng)指Linux所支持的文件系統(tǒng),如ext2,fat等,設(shè)備驅(qū)動(dòng)程序指為每一種硬件控制器所編寫的設(shè)備驅(qū)動(dòng)程序模塊。4網(wǎng)絡(luò)接口(NET)提供了對(duì)各種網(wǎng)絡(luò)標(biāo)準(zhǔn)的存取和各種網(wǎng)絡(luò)硬件的支持。網(wǎng)絡(luò)接口可分為網(wǎng)絡(luò)協(xié)議和網(wǎng)絡(luò)驅(qū)動(dòng)程序。網(wǎng)絡(luò)協(xié)議部分負(fù)責(zé)實(shí)現(xiàn)每一種可能的網(wǎng)絡(luò)傳輸協(xié)議。網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序負(fù)責(zé)與硬件設(shè)備通訊,每一種可能的硬件設(shè)備都有相應(yīng)的設(shè)備驅(qū)動(dòng)程序。5進(jìn)程間通訊(IPC)支持進(jìn)程間各種通信機(jī)制。圖2-1Linux內(nèi)核的五個(gè)子系統(tǒng)如圖2-1處于中心位置的進(jìn)程調(diào)度,所有其它的子系統(tǒng)都依賴它,因?yàn)槊總€(gè)子系統(tǒng)都需要掛起或恢復(fù)進(jìn)程。一般情況下,當(dāng)一個(gè)進(jìn)程等待硬件操作完成時(shí),它被掛起;當(dāng)操作真正完成時(shí),進(jìn)程被恢復(fù)執(zhí)行。例如,當(dāng)一個(gè)進(jìn)程通過(guò)網(wǎng)絡(luò)發(fā)送一條消息時(shí),網(wǎng)絡(luò)接口需要掛起發(fā)送進(jìn)程,直到硬件成功地完成消息的發(fā)送,當(dāng)消息被成功的發(fā)送出去以后,網(wǎng)絡(luò)接口給進(jìn)程返回一個(gè)代碼,表示操作的成功或失敗。其他子系統(tǒng)以相似的理由依賴于進(jìn)程調(diào)度。2.2Linux進(jìn)程管理如果說(shuō)操作系統(tǒng)是開發(fā)者所依賴的框架,那么,進(jìn)程就是由這個(gè)框架所承擔(dān)和管理的基本或從單元。進(jìn)程是一個(gè)動(dòng)態(tài)的實(shí)用系統(tǒng)資源、處于活動(dòng)狀態(tài)的程序。Linux是一個(gè)多任務(wù)操作程序,程序調(diào)度器使用合適的調(diào)用算法來(lái)調(diào)用進(jìn)程。Linux進(jìn)程管理由進(jìn)程控制塊、進(jìn)程調(diào)度、中斷處理、任務(wù)隊(duì)列、定時(shí)器、bottomhalf隊(duì)列、系統(tǒng)調(diào)用、進(jìn)程通信等部分組成。[7]一個(gè)程序可啟動(dòng)多次,它的每個(gè)運(yùn)行副本都有自己的進(jìn)程。進(jìn)程的生命周期分為進(jìn)程的產(chǎn)生、執(zhí)行和結(jié)束三個(gè)部分。2.2.1進(jìn)程描述符在內(nèi)核中,進(jìn)程描述符是一個(gè)名為task_struct的結(jié)構(gòu)體,用于保存進(jìn)程的屬性和其他信息,我們可以在這個(gè)結(jié)構(gòu)體中找到與進(jìn)程有關(guān)的所有內(nèi)核信息。在其生命周期內(nèi),進(jìn)程要與內(nèi)核的方方面面,“諸如內(nèi)存管理和調(diào)度”等打交道,因此,除了UNIX進(jìn)程的標(biāo)準(zhǔn)屬性外,進(jìn)程描述符也保存了在上述交互過(guò)程中的相關(guān)信息。內(nèi)核用循環(huán)雙向鏈表task_list存放所有進(jìn)程描述符,同時(shí)借助全局變量current保存當(dāng)前運(yùn)行進(jìn)程的task_struct。數(shù)組task包含指向系統(tǒng)中所有task_struct結(jié)構(gòu)的指針。系統(tǒng)中的最大進(jìn)程數(shù)目受task數(shù)組大小的限制,默認(rèn)值一般為512。創(chuàng)建新進(jìn)程時(shí),Linux將從系統(tǒng)內(nèi)存中分配一個(gè)task_struct結(jié)構(gòu),并將其加入task數(shù)組。操作系統(tǒng)初始化后,建立init進(jìn)程,它創(chuàng)建第一個(gè)task_struct數(shù)據(jù)結(jié)構(gòu)INIT_TASK。當(dāng)前運(yùn)行進(jìn)程的結(jié)構(gòu)用current指針來(lái)表示。在進(jìn)程生命周期中,進(jìn)程描述符必須保存的信息的類型有[8]:進(jìn)程的屬性進(jìn)程間的關(guān)系進(jìn)程的內(nèi)存空間文件管理信號(hào)量管理進(jìn)程的可信度資源限制與調(diào)度相關(guān)的域下面我們來(lái)了解一些Task_struct結(jié)構(gòu)中與嵌入式開發(fā)相關(guān)的域。進(jìn)程狀態(tài)(volatilelongstate)進(jìn)程狀態(tài)定義有如下幾種://正在運(yùn)行的進(jìn)程或在Running隊(duì)列中準(zhǔn)備運(yùn)行的進(jìn)程#defineTASK_RUNNING 0//處于等待隊(duì)列中的進(jìn)程,等資源有效時(shí)喚醒進(jìn)入就緒隊(duì)列run-queue#defineTASK_INTERRUPTIBLE 1//處于等待隊(duì)列中的進(jìn)程,等資源有效時(shí)喚醒,但不可被其他進(jìn)程中斷#defineTASK_UNINTERRUPTIBLE 2//進(jìn)程暫停,通過(guò)其他進(jìn)程才能喚醒#defineTASK_STOPPED 4//進(jìn)程已經(jīng)被殺死,但父進(jìn)程還沒(méi)有調(diào)用sys_wait()#defineTASK_ZOMBIE 8//僵死狀態(tài)的進(jìn)程,進(jìn)程已經(jīng)結(jié)束運(yùn)行且釋放大部分資源,但未釋放其進(jìn)程塊#defineTASK_DEAD 16進(jìn)程狀態(tài)轉(zhuǎn)換如圖2-2所示,用戶進(jìn)程由do_fork()函數(shù)創(chuàng)建,它也是fork系統(tǒng)調(diào)用的執(zhí)行者。do_fork()創(chuàng)建一個(gè)新的進(jìn)程,繼承父進(jìn)程現(xiàn)有資源,初始化進(jìn)程時(shí)鐘、信號(hào)、時(shí)間等數(shù)據(jù)。完成子進(jìn)程初始化后,父進(jìn)程將它掛到就緒隊(duì)列run-queue,返回子進(jìn)程的pid。圖2.2Linux進(jìn)程狀態(tài)轉(zhuǎn)換圖進(jìn)程創(chuàng)建時(shí)的狀態(tài)為TASK_UNINTERRUPTIBLE,在do_fork()結(jié)束前被父進(jìn)程喚醒后,變?yōu)門ASK_RUNNING。處于TASK_RUNNING狀態(tài)的進(jìn)程被移到run-queue隊(duì)列中,在適當(dāng)時(shí)候由schedule()按CPU調(diào)度算法選中,獲得CPU。獲得CPU而正在運(yùn)行的進(jìn)程若申請(qǐng)不到某個(gè)資源,則調(diào)用sleep_on()或interruptible_sleep_on()睡眠,其task_struct掛到相應(yīng)的waitqueue。如果調(diào)用sleep_on()睡眠,則其狀態(tài)變?yōu)門ASK_UNINTERRUPTIBLE?;蛘撸绻{(diào)用interruptible_sleep_on()睡眠,則其狀態(tài)變?yōu)門ASK_INTERRUPTIBLE。sleep_on()或interruptible_sleep_on()將調(diào)用schedule()函數(shù)把睡眠進(jìn)程釋放的CPU分配給run-queue隊(duì)列的某個(gè)就緒進(jìn)程。狀態(tài)為TASK_INTERRUPTIBLE的睡眠進(jìn)程當(dāng)它申請(qǐng)的資源有效時(shí)被喚醒(如wake_up_interruptible()),也可以由信號(hào)(signal)或定時(shí)中斷喚醒。而狀態(tài)為TASK_UNINTERRUPTIBLE的睡眠進(jìn)程只有當(dāng)它申請(qǐng)的資源有效時(shí)被喚醒(如wake_up()),不能被信號(hào)(signal)、定時(shí)中斷喚醒。喚醒后,進(jìn)程狀態(tài)改為TASK_RUNNING,并進(jìn)入run-queue隊(duì)列。進(jìn)程執(zhí)行系統(tǒng)調(diào)用sys_exit()或收到SIG_KILL信號(hào)而調(diào)用do_exit()時(shí),進(jìn)程狀態(tài)變?yōu)門ASK_ZOMBIE,釋放所申請(qǐng)資源。同時(shí)啟動(dòng)schedule()把CPU分配給run-queue隊(duì)列中其它就緒進(jìn)程。若進(jìn)程通過(guò)系統(tǒng)調(diào)用設(shè)置PF_SYSTRACE,則在系統(tǒng)調(diào)用返回前,進(jìn)入syscall_trace(),狀態(tài)變?yōu)門ASK_STOPPED,CPU分配給run-queue隊(duì)列中其它就緒進(jìn)程。只有通過(guò)其它進(jìn)程發(fā)送SIG_KILL或SIG_CONT,才能把TASK_STOPPED進(jìn)程喚醒。重新進(jìn)入run-queue隊(duì)列。進(jìn)程優(yōu)先級(jí)
intprio,優(yōu)先級(jí),在0~(MAX_PRIO)-1之間取值(MAX_PRIO定義為140),其中0~(MAX_RT_PRIO)-1(MAX_RT_PRIO定義為100)屬于實(shí)時(shí)進(jìn)程范圍。在內(nèi)核2.6版本中,動(dòng)態(tài)優(yōu)先級(jí)獨(dú)立計(jì)算,通過(guò)priority_array結(jié)構(gòu)按優(yōu)先級(jí)排序,存儲(chǔ)在進(jìn)程的task_struct中。
intstatic_prio,靜態(tài)優(yōu)先級(jí),與Linux2.4的nice值意義相同,但轉(zhuǎn)換到與prio相同的取值區(qū)間。nice值沿用Linux的傳統(tǒng),在-20~19之間變動(dòng),數(shù)值越大,進(jìn)程的優(yōu)先級(jí)越低。nice是用戶可維護(hù)的,但僅影響非實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)。Linux2.6內(nèi)核中不再存儲(chǔ)nice值,而代之以static_prio。進(jìn)程初始時(shí)間片的大小僅取決于進(jìn)程的靜態(tài)優(yōu)先級(jí),這一點(diǎn)無(wú)論是實(shí)時(shí)進(jìn)程還是非實(shí)時(shí)進(jìn)程都一樣,不過(guò)實(shí)時(shí)進(jìn)程的static_prio不參與優(yōu)先級(jí)計(jì)算。
nice與static_prio之間的關(guān)系如下:
static_prio=MAX_RT_PRIO+nice+20prio_array_t*array
它是優(yōu)先級(jí)數(shù)組,它將進(jìn)程優(yōu)先級(jí)為序號(hào)組成數(shù)組。它也是runqueue結(jié)構(gòu)的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。實(shí)時(shí)優(yōu)先級(jí)
rt_priority給出實(shí)時(shí)進(jìn)程的優(yōu)先級(jí),而rt_priority+1000則表示每次獲得CPU后,可使用的時(shí)間(按jiffy計(jì)算)。實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)可通過(guò)系統(tǒng)調(diào)用sys_sched_setschedule()改變,實(shí)際的工作是由setscheduler()完成得。
在Linux2.6內(nèi)核中,候選進(jìn)程是直接按算法排序的優(yōu)先級(jí)隊(duì)列數(shù)組中選取出來(lái)的,而優(yōu)先級(jí)的計(jì)算分散到多出進(jìn)行。進(jìn)程在適當(dāng)?shù)臅r(shí)機(jī)就會(huì)計(jì)算動(dòng)態(tài)優(yōu)先級(jí)。同時(shí),影響動(dòng)態(tài)優(yōu)先級(jí)的因素集中反映在sleep_avg變量上。只要進(jìn)程狀態(tài)發(fā)生改變,內(nèi)核就有可能計(jì)算并設(shè)置進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)。activated
activated表示進(jìn)程由于某種原因進(jìn)入就緒態(tài),這一原因會(huì)影響到調(diào)度優(yōu)先級(jí)的計(jì)算。activated有四個(gè)值:-1,進(jìn)程從TASK_UNINTERRUPTIBLE狀態(tài)被喚醒0,默認(rèn)值,進(jìn)程原本就處于就緒態(tài)1,進(jìn)程從TASK_INTERRUPTIBLE狀態(tài)被喚醒,且不在中斷上下文中2,進(jìn)程從TASK_INTERRUPTIBLE狀態(tài)被喚醒,且在中斷上下文中activated初值為0,在兩個(gè)地方修改:一個(gè)是在schedule()中,被恢復(fù)為0;另一個(gè)就是activate_task(),這個(gè)函數(shù)由try_to_wake_up()函數(shù)調(diào)用,用于激活休眠狀態(tài)。sleep_avg
進(jìn)程的平均等待時(shí)間(以nanosecond為計(jì)算單位),在0到NS_MAX_SLEEP_AVG之間取值,初值為0,相當(dāng)于進(jìn)程等待時(shí)間與運(yùn)行時(shí)間的差值。sleep_avg所代表的含義比較豐富,既可用于評(píng)價(jià)該進(jìn)程的“交互程度”,又可用于表示該進(jìn)程需要運(yùn)行的緊迫度。這個(gè)值是動(dòng)態(tài)優(yōu)先級(jí)計(jì)算的關(guān)鍵因子,sleep_avg越大,計(jì)算出來(lái)的進(jìn)程優(yōu)先級(jí)也越高(數(shù)值越小)。
sleep_avg反映了調(diào)度系統(tǒng)的兩種策略:交互式進(jìn)程優(yōu)先與分時(shí)系統(tǒng)的公平共享。time_slice
time_slice變量表示進(jìn)程的運(yùn)行時(shí)間片剩余大小。進(jìn)程默認(rèn)時(shí)間片與進(jìn)程的靜態(tài)優(yōu)先級(jí)相關(guān)。在進(jìn)程創(chuàng)建時(shí),它與父進(jìn)程平分時(shí)間片,在運(yùn)行過(guò)程中遞減,一旦歸零,則按static_prio靜態(tài)優(yōu)先級(jí)值重新賦予基準(zhǔn)值,并請(qǐng)求調(diào)度。時(shí)間片的遞減和重置在時(shí)鐘中斷中進(jìn)行(scheduler_tick()),除此之外,time_slice值主要在進(jìn)程創(chuàng)建和進(jìn)程退出的過(guò)程中變化。policy
policy可以決定進(jìn)程的類型,不同類型的進(jìn)程運(yùn)行時(shí)的調(diào)度策略也不同(例如,分時(shí)進(jìn)程和實(shí)時(shí)進(jìn)程的調(diào)度策略不同)。進(jìn)程的類型及大影響到其調(diào)度優(yōu)先級(jí)。2.2.2進(jìn)程調(diào)度在linux2.6中,采用O(1)調(diào)度算法,調(diào)度器開銷恒定,與當(dāng)前系統(tǒng)負(fù)載無(wú)關(guān),實(shí)時(shí)性能更好。Linux2.4中的就緒隊(duì)列是一個(gè)簡(jiǎn)單的以runqueue_head為頭的雙向鏈表,而在Linux2.6中,每個(gè)CPU都將維護(hù)一個(gè)自己的runqueue結(jié)構(gòu)的就緒隊(duì)列,這將大大減少競(jìng)爭(zhēng)。每個(gè)CPU的就緒隊(duì)列按時(shí)間片是否用完分為兩部分,分別通過(guò)active指針和expired指針訪問(wèn)。[9]Acrive指向時(shí)間片沒(méi)有用完的、當(dāng)前可被調(diào)度的就緒進(jìn)程;expired指向時(shí)間片已經(jīng)用完的就緒進(jìn)程。active中的進(jìn)程一旦用完了自己的時(shí)間片,就被轉(zhuǎn)移到expired中,并設(shè)置好新的初始時(shí)間片;而當(dāng)actived為空時(shí),則表示當(dāng)前所有進(jìn)程的時(shí)間片都消耗完了,此時(shí),active和expired進(jìn)行一次對(duì)調(diào),重新開始下一輪的時(shí)間片遞減過(guò)程。而runqueue就是調(diào)度程序操作的對(duì)象。進(jìn)程在初始化并放入運(yùn)行隊(duì)列后,在某個(gè)時(shí)刻,它應(yīng)該獲得對(duì)CPU的訪問(wèn)。負(fù)責(zé)把CPU的控制權(quán)傳遞到不同的兩個(gè)函數(shù)是schedule()和scheduler_tick()。scheduler_tick()是一個(gè)由內(nèi)核周期性調(diào)用的系統(tǒng)定時(shí)器,它把進(jìn)程標(biāo)記為需重新調(diào)度。一般定時(shí)事件發(fā)生時(shí),當(dāng)前的進(jìn)程就被保存起來(lái),Linux內(nèi)核接管對(duì)CPU的控制,而當(dāng)定時(shí)事件完成后,Linux內(nèi)核通常把控制權(quán)傳回被保存的進(jìn)程。然而,當(dāng)所保存的進(jìn)程被標(biāo)記成需重新調(diào)度時(shí),并不一定選擇內(nèi)核接管控制前正在執(zhí)行的那個(gè)進(jìn)程,而是內(nèi)核調(diào)用schedule()來(lái)選擇需要激活哪一個(gè)進(jìn)程。圖2-3調(diào)度過(guò)程圖2-3說(shuō)明隨著時(shí)間的推移,如何在不同的進(jìn)程之間傳遞CPU。我們看到,進(jìn)程A最先擁有CPU的控制權(quán)并正在執(zhí)行。系統(tǒng)定時(shí)scheduler_tick()執(zhí)行,從A獲取對(duì)CPU的控制權(quán),此時(shí)scheduler_tick()把A標(biāo)記為需要重新調(diào)度。Linux內(nèi)核調(diào)用scheduler(),scheduler()選擇進(jìn)程B,因此CPU的控制權(quán)被交給B。進(jìn)程B執(zhí)行一會(huì)兒,然后自動(dòng)放棄CPU。這通常發(fā)生在進(jìn)程等待資源的時(shí)候。進(jìn)程B調(diào)用scheduler(),scheduler()選擇進(jìn)程C繼續(xù)執(zhí)行。進(jìn)程C執(zhí)行,直到scheduler_tick()發(fā)生,scheduler_tick()不把進(jìn)程C標(biāo)記為需要調(diào)度。這導(dǎo)致了scheduler()不被調(diào)用,因此,進(jìn)程C再次獲得CPU的控制權(quán)。通過(guò)調(diào)用scheduler(),進(jìn)程C放棄CPU,scheduler()決定進(jìn)程A應(yīng)該獲得CPU的控制權(quán),進(jìn)程A再次開始執(zhí)行。我們首先分析scheduler(),Linux內(nèi)核利用它決定哪個(gè)進(jìn)程接下來(lái)要執(zhí)行,然后,在分析scheduler_tick(),內(nèi)核利用它決定哪個(gè)進(jìn)程必須讓出CPU。這兩個(gè)函數(shù)組合的結(jié)果說(shuō)明了調(diào)度程序的控制流程[10]。函數(shù)schedule分析在include/Linux/sched.h中有調(diào)度策略定義如圖2-4:圖2-4Linux進(jìn)程狀態(tài)定義策略進(jìn)程的task_struct結(jié)構(gòu)中成員policy是進(jìn)程的調(diào)度策略,它的值為上述三種策略之一,進(jìn)程分為實(shí)時(shí)進(jìn)程和普通進(jìn)程,實(shí)時(shí)進(jìn)程優(yōu)先于普通進(jìn)程運(yùn)行。rt_priority是實(shí)時(shí)進(jìn)程的優(yōu)先級(jí),它比普通進(jìn)程的priority高。當(dāng)系統(tǒng)中有一個(gè)實(shí)時(shí)進(jìn)程運(yùn)行時(shí),則SCHED_NORMAL進(jìn)程不能在任何CPU運(yùn)行,只有root用戶能夠用系統(tǒng)調(diào)用sched_setscheduler來(lái)修改當(dāng)前進(jìn)程的優(yōu)先級(jí)。[10]函數(shù)schedule的功能是選擇一個(gè)合適的進(jìn)程在CPU上運(yùn)行,它的基本流程分為五個(gè)操作步驟:清理當(dāng)前運(yùn)行中的進(jìn)程。選擇下一個(gè)投入運(yùn)行的進(jìn)程。設(shè)置新進(jìn)程的運(yùn)行環(huán)境執(zhí)行進(jìn)程上下文切換。后期處理。進(jìn)程調(diào)度有直接啟動(dòng)調(diào)度和被動(dòng)啟動(dòng)調(diào)動(dòng)兩種方式,在不同的方式下調(diào)度執(zhí)行的步驟是不一樣的。直接啟動(dòng)調(diào)度
直接啟動(dòng)調(diào)度發(fā)生在當(dāng)前進(jìn)程因等待資源而需要進(jìn)入被阻塞狀態(tài)時(shí),調(diào)度程序執(zhí)行的步驟如下:把當(dāng)前進(jìn)程(全局變量current指向task_struct變量)放到適當(dāng)?shù)牡却?duì)列里;把當(dāng)前進(jìn)程的state設(shè)為TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE調(diào)用schedule(),準(zhǔn)備讓新的進(jìn)程掌握CPU;檢查當(dāng)前進(jìn)程所需的資源是否可用,如果是,則把當(dāng)前進(jìn)程從等待隊(duì)列里刪除,否則會(huì)到步驟b被動(dòng)調(diào)度
通過(guò)在當(dāng)前進(jìn)程的need_resched設(shè)為1來(lái)實(shí)現(xiàn)被動(dòng)調(diào)度,每次調(diào)入一個(gè)用戶太進(jìn)程之前,這個(gè)變量的值都會(huì)被檢查,來(lái)決定是否調(diào)用函數(shù)schedule()來(lái)實(shí)現(xiàn)調(diào)度。具體執(zhí)行方式為:當(dāng)當(dāng)前進(jìn)程用完了它的CPU時(shí)間片,update_process_times()重新進(jìn)行計(jì)算。當(dāng)一個(gè)進(jìn)程被喚醒,而且他的優(yōu)先級(jí)比當(dāng)前進(jìn)程高。Wake_up_process()調(diào)用reschedule_idle(),設(shè)置當(dāng)前進(jìn)程的need_resched,使被喚醒的進(jìn)程盡快掌握CPU當(dāng)sched_setscheduler()或sched_yield()系統(tǒng)調(diào)用被調(diào)用的進(jìn)程函數(shù)scheduler_tick分析通過(guò)調(diào)用schedule()可使進(jìn)程自動(dòng)放棄CPU。在向要睡眠或等待信號(hào)發(fā)生的內(nèi)核代碼及設(shè)備驅(qū)動(dòng)中。這個(gè)函數(shù)用得非常普遍。若其他進(jìn)程想要連續(xù)的使用CPU,系統(tǒng)定時(shí)器必須告訴它們讓出CPU。Linux內(nèi)核定時(shí)地奪取CPU,然后執(zhí)行基于定時(shí)器的許多任務(wù)。其中,這些任務(wù)之一就是scheduler_tick(),它是內(nèi)核強(qiáng)迫一個(gè)進(jìn)程放棄CPU的函數(shù)。首先scheduler_tick先收集CPU的統(tǒng)計(jì),然后查看當(dāng)前進(jìn)程是否不再活躍。如果進(jìn)程已經(jīng)過(guò)期,調(diào)度程序設(shè)置進(jìn)程的重新調(diào)度標(biāo)志,并跳轉(zhuǎn)到scheduler_tick()函數(shù)的結(jié)尾。如果得知當(dāng)前進(jìn)程正在運(yùn)行,調(diào)度程序就先為剝奪CPU控制權(quán)而申請(qǐng)運(yùn)行隊(duì)列鎖。先考慮最簡(jiǎn)單的情況。如果當(dāng)前進(jìn)程是實(shí)時(shí)進(jìn)程,由于實(shí)時(shí)進(jìn)程總是擁有比其他任何進(jìn)程都搞得優(yōu)先級(jí),當(dāng)該進(jìn)程是FIFO進(jìn)程并且正在運(yùn)行,進(jìn)程應(yīng)該繼續(xù)它的操作,因此,我們跳轉(zhuǎn)到函數(shù)的末尾并釋放運(yùn)行隊(duì)列鎖。如果當(dāng)前進(jìn)程是時(shí)間片輪轉(zhuǎn)實(shí)時(shí)進(jìn)程,我們就減小其時(shí)間片,然后調(diào)度另一個(gè)輪轉(zhuǎn)實(shí)時(shí)進(jìn)程,當(dāng)前進(jìn)程通過(guò)task_timeslice()計(jì)算其新的時(shí)間按片,最后通過(guò)從運(yùn)行隊(duì)列的活躍數(shù)組刪除進(jìn)程并把其添加回活躍數(shù)組,進(jìn)程被放到輪轉(zhuǎn)實(shí)時(shí)進(jìn)程鏈表的末尾,最后釋放運(yùn)行隊(duì)列鎖。通過(guò)了上面的嘗試,如果調(diào)度程序發(fā)現(xiàn)當(dāng)前并非實(shí)時(shí)進(jìn)程。它減小進(jìn)程的時(shí)間片,如果時(shí)間片被耗盡。調(diào)度程序從活躍數(shù)組刪除進(jìn)程并設(shè)置它的需要重新調(diào)度標(biāo)志。重新計(jì)算進(jìn)程的優(yōu)先級(jí)并重置它的時(shí)間片。最后一種情況,就是進(jìn)程正在運(yùn)行并且還有剩余時(shí)間片可運(yùn)行。調(diào)度程序必須確保擁有大時(shí)間片的進(jìn)程不會(huì)獨(dú)占CPU。如果進(jìn)程是交互式的,擁有多余TIMESLICE_GRANULARITY的時(shí)間片,而且是活躍的,調(diào)度程序就將它從活躍隊(duì)列中刪除。然后,重新調(diào)度標(biāo)志置位,重新計(jì)算它的優(yōu)先級(jí)后被放回運(yùn)行隊(duì)列的活躍數(shù)組,這確保了擁有大時(shí)間片的某個(gè)優(yōu)先權(quán)的進(jìn)程不會(huì)餓死同等優(yōu)先權(quán)的其它進(jìn)程。2.2.2搶占搶占指一個(gè)進(jìn)程到另一個(gè)進(jìn)程的切換。前面介紹了schedule()和scheduler_tick()是如何決定接下來(lái)要切換哪一個(gè)進(jìn)程的,但沒(méi)有提及Linux內(nèi)核是如何決定何時(shí)進(jìn)行切換的。2.6內(nèi)核引入了內(nèi)核搶占,這意味著用戶空間的程序和內(nèi)核空間的程序能夠在各種時(shí)刻被切換。下面將從顯式和隱式分別對(duì)內(nèi)核與用戶搶占進(jìn)行描述。[11]顯式內(nèi)核搶占這種情況發(fā)生內(nèi)核調(diào)用schedule()時(shí)的內(nèi)核空間,內(nèi)核代碼可以用兩種方式調(diào)用schedule():直接調(diào)用schedule()或者通過(guò)阻塞調(diào)用。當(dāng)顯式地?fù)屨純?nèi)核時(shí),例如,在wait_queue等待隊(duì)列中設(shè)備驅(qū)動(dòng)程序在等待時(shí),控制權(quán)被簡(jiǎn)單地傳遞到調(diào)度程序,從而新的進(jìn)程被選中執(zhí)行。隱式用戶搶占當(dāng)內(nèi)核處理完內(nèi)核空間的進(jìn)程并準(zhǔn)備把控制權(quán)傳遞到用戶空間的進(jìn)程時(shí),它首先查看應(yīng)該把控制權(quán)傳遞到哪一個(gè)用戶空間的進(jìn)程。而這個(gè)進(jìn)程也許不是傳遞其控制權(quán)到內(nèi)核的那個(gè)用戶空間進(jìn)程。例如,如果進(jìn)程A調(diào)用了系統(tǒng)調(diào)用,系統(tǒng)調(diào)用完成之后,內(nèi)核可能把系統(tǒng)的控制權(quán)傳遞給進(jìn)程B。出現(xiàn)這種情況的主要原因是系統(tǒng)中的每一個(gè)進(jìn)程有一個(gè)“必須重新調(diào)度”標(biāo)志,在進(jìn)程應(yīng)該被重新調(diào)度的任何時(shí)候設(shè)置它。當(dāng)內(nèi)核正在向用戶空間返回時(shí),如同schedule()和scheduler_tick()中描述的那樣,它選擇一個(gè)進(jìn)程,并把控制權(quán)傳遞給該進(jìn)程。盡管scheduler_tick()能夠把進(jìn)程標(biāo)記為需要重新調(diào)度,但是只有schedule()能夠?qū)@個(gè)標(biāo)記進(jìn)行操作。schedule()反復(fù)選擇一個(gè)新進(jìn)程來(lái)執(zhí)行,直到新選擇的進(jìn)程不需要被重新調(diào)度。schedule()完成后,新進(jìn)程擁有對(duì)CPU的控制權(quán)。因此,當(dāng)進(jìn)程正在運(yùn)行時(shí),系統(tǒng)定時(shí)器引起一個(gè)觸發(fā)scheduler_tick()的中斷。scheduler_tick()能夠標(biāo)記哪個(gè)任務(wù)需要重新調(diào)度,并能把它移動(dòng)至到期數(shù)組。在內(nèi)核操作完成之后,scheduler_tick()的后面可能緊接著其他中斷,內(nèi)核將繼續(xù)擁有對(duì)處理器的控制權(quán)。調(diào)用schedule()選擇下一個(gè)要運(yùn)行的進(jìn)程。這樣看來(lái),scheduler_tick()標(biāo)記進(jìn)程并重排隊(duì)列,而schedule()選擇下一個(gè)進(jìn)程并傳遞CPU的控制權(quán)。隱式內(nèi)核搶占Linux2.6中新增了隱式內(nèi)核搶占的實(shí)現(xiàn)。當(dāng)一個(gè)內(nèi)核進(jìn)程擁有對(duì)CPU的控制權(quán)時(shí),僅當(dāng)其當(dāng)前沒(méi)有持有任何鎖時(shí),這個(gè)內(nèi)核進(jìn)程才能被另一個(gè)內(nèi)核進(jìn)程所搶占。每個(gè)進(jìn)程有一個(gè)域preempt_count,它標(biāo)記進(jìn)程是否可以搶占。每當(dāng)進(jìn)程獲得一個(gè)鎖時(shí),則該計(jì)數(shù)增加,每當(dāng)進(jìn)程釋放一個(gè)鎖時(shí)減少。當(dāng)一個(gè)進(jìn)程仍然有一個(gè)正的preempt_count值,就把CPU控制權(quán)返回給當(dāng)前進(jìn)程。如果當(dāng)前進(jìn)程沒(méi)有鎖,因?yàn)閜reempt_count是0且中斷請(qǐng)求是激活的,這樣該進(jìn)程就可能會(huì)被搶占。[10]2.2.3調(diào)度器的實(shí)時(shí)性能Linux2.6對(duì)實(shí)時(shí)性能的改進(jìn)
Linux2.6內(nèi)核調(diào)度系統(tǒng)對(duì)調(diào)度的實(shí)時(shí)性作了改進(jìn),它體現(xiàn)了內(nèi)核搶占和O(1)調(diào)度,這加快了實(shí)時(shí)進(jìn)程的響應(yīng)。但Linux2.6調(diào)度系統(tǒng)僅提供了對(duì)CPU資源的剝奪能力,因此它的實(shí)時(shí)性并沒(méi)有得到根本改觀。所以Linux2.6只能作為軟實(shí)時(shí)操作系統(tǒng)。實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)
在Linux2.4中,實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)通過(guò)rt_priority值表示,與非實(shí)時(shí)進(jìn)程不同。Linux2.6在靜態(tài)優(yōu)先級(jí)之外引入了動(dòng)態(tài)優(yōu)先級(jí)屬性,并用它同時(shí)表示實(shí)時(shí)進(jìn)程和非實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)。進(jìn)程的靜態(tài)優(yōu)先級(jí)是計(jì)算進(jìn)程初始時(shí)間片的基礎(chǔ),動(dòng)態(tài)優(yōu)先級(jí)則決定了進(jìn)程的實(shí)際調(diào)度優(yōu)先順序。因?yàn)閷?shí)時(shí)進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)在setscheduler()中設(shè)置,并不隨進(jìn)程的運(yùn)行而改變。所以實(shí)時(shí)進(jìn)程的靜態(tài)優(yōu)先級(jí)僅用于計(jì)算時(shí)間片,而動(dòng)態(tài)優(yōu)先級(jí)則相當(dāng)于靜態(tài)。實(shí)時(shí)調(diào)度
linux2.4種的SCHED_RR和SCHED_FIFO兩種實(shí)時(shí)調(diào)度策略在Linux2.6中未做改變,兩類實(shí)時(shí)進(jìn)程都回保持在active就緒隊(duì)列中運(yùn)行,只是因?yàn)長(zhǎng)inux2.6內(nèi)核是可搶占的,實(shí)時(shí)進(jìn)程(特別是核心級(jí)的實(shí)時(shí)進(jìn)程)更能迅速地對(duì)環(huán)境的改變(比如出現(xiàn)更高優(yōu)先級(jí)進(jìn)程)作出反應(yīng)。[11]3構(gòu)造嵌入式Linux系統(tǒng)Linux作為一種通用操作系統(tǒng),其最初的設(shè)計(jì)是用于桌面系統(tǒng)或者小型服務(wù)器。在將Linux用于嵌入式系統(tǒng)中時(shí),由于受到嵌入式軟/硬件環(huán)境的制約,需要對(duì)Linux內(nèi)核做一些改進(jìn),使它能更好地為嵌入式系統(tǒng)服務(wù)。在這些改進(jìn)中,進(jìn)程管理是相當(dāng)重要的一環(huán)。從芯片到外圍電路再到人機(jī)接口,嵌入式系統(tǒng)的這些硬件設(shè)備與普通PC是截然不同的。由于降低成本和功耗,嵌入式系統(tǒng)CPU可能不帶MMU(存儲(chǔ)器管理單元),使用的存儲(chǔ)設(shè)備ROM、Flash及RAM的容量較小,這些因素決定了須改變Linux進(jìn)程管理,以適應(yīng)存儲(chǔ)系統(tǒng)方面的變化。[11]3.1uClinux結(jié)局方案Lineo公司的uClinux就是專門針對(duì)無(wú)MMU處理器的嵌入式設(shè)備的Linux變種。由于uClinux沒(méi)有MMU,在實(shí)現(xiàn)多進(jìn)程時(shí)(fork調(diào)用產(chǎn)生子進(jìn)程)須實(shí)現(xiàn)數(shù)據(jù)保護(hù)。由于uClinux的多進(jìn)程管理是通過(guò)vfork來(lái)實(shí)現(xiàn)的,因此fork等于vfork。這意味著uClinux系統(tǒng)fork調(diào)用完成后,或者子進(jìn)程代替父進(jìn)程執(zhí)行(此時(shí)父進(jìn)程已經(jīng)sleep),直到子進(jìn)程調(diào)用exit推出;或者調(diào)用exec執(zhí)行一個(gè)新進(jìn)程,此時(shí)將產(chǎn)生執(zhí)行文件加載,即使這個(gè)進(jìn)程只是父進(jìn)程的拷貝,這個(gè)過(guò)程也是不可避免的。當(dāng)子進(jìn)程執(zhí)行exit或exec后,子進(jìn)程使用wakeup把父進(jìn)程喚醒,使父進(jìn)程繼續(xù)往下執(zhí)行。uClinux的這種多進(jìn)程實(shí)現(xiàn)機(jī)制與它的內(nèi)存管理緊密相關(guān)。uClinux針對(duì)沒(méi)有MMU的處理器開發(fā),所以須使用一種flat方式的內(nèi)存管理模式。在啟動(dòng)新的應(yīng)用程序時(shí),系統(tǒng)必須為應(yīng)用程序分配存儲(chǔ)空間。uClinux本身并沒(méi)于關(guān)注實(shí)時(shí)問(wèn)題,它并不時(shí)為了Linux的實(shí)時(shí)性而提出的。因此若將uClinux用于實(shí)時(shí)性要求較高的場(chǎng)合,則需要對(duì)其內(nèi)核做必要的改進(jìn)。嵌入式Linux的另一個(gè)版本RT-Linux關(guān)注實(shí)時(shí)問(wèn)題。RT-linux把普通Linux的內(nèi)核當(dāng)成一個(gè)任務(wù)運(yùn)行,同時(shí)還管理了實(shí)時(shí)進(jìn)程,而非實(shí)時(shí)進(jìn)程則交給普通Linux內(nèi)核處理。這種方法已廣泛應(yīng)用于增強(qiáng)操作系統(tǒng)得實(shí)時(shí)性,包括一些商業(yè)版Unix系統(tǒng)和WindowNT等等。這種方法的優(yōu)點(diǎn)是:實(shí)現(xiàn)簡(jiǎn)單,且實(shí)時(shí)性能容易檢驗(yàn);非實(shí)時(shí)系統(tǒng)運(yùn)行于標(biāo)準(zhǔn)Linux系統(tǒng),與其他Linux商用版本之間保持了很好的兼容性;可支持硬實(shí)時(shí)時(shí)鐘的應(yīng)用。uClinux可使用RT-linux的patch,從而增強(qiáng)uClinux的實(shí)時(shí)性,使得uClinux可應(yīng)用于工業(yè)標(biāo)準(zhǔn)、進(jìn)程控制等一些實(shí)時(shí)要求較高的場(chǎng)合。在普通PC中,外部存儲(chǔ)介質(zhì)一般都是使用IDE硬盤等傳統(tǒng)的外存設(shè)備;而在嵌入式系統(tǒng)中,各種特殊應(yīng)用目的對(duì)存儲(chǔ)設(shè)備提出了各種各樣的要求,所以在不同的場(chǎng)合,需要因地制宜地選擇存儲(chǔ)設(shè)備。目前,F(xiàn)lash存儲(chǔ)設(shè)備由于其安全性高,存儲(chǔ)密度大,體積小,價(jià)格相對(duì)低廉,成為嵌入式領(lǐng)域中最受歡迎的一類存儲(chǔ)器。在嵌入式系統(tǒng)中使用Flash存儲(chǔ)器,可只進(jìn)行只讀訪問(wèn),再將內(nèi)核與文件系統(tǒng)寫到Flash上之后,不需要再對(duì)Flash進(jìn)行寫操作。在這種情況下,只需要將Flash作為普通ROM來(lái)使用,或輔以romfs和cramfs等,即可滿足要求。在運(yùn)行時(shí),系統(tǒng)會(huì)把需要操作的文件和目錄提取到內(nèi)存中進(jìn)行操作。由于不能再Flash上寫數(shù)據(jù),所以運(yùn)行時(shí)的欣喜都不可保存于Flash存儲(chǔ)設(shè)備中。所以對(duì)Flash存儲(chǔ)設(shè)備的管理非常簡(jiǎn)單,與普通的ROM沒(méi)有什么區(qū)別。uClinux系統(tǒng)采用romfs(romfilesystem)文件系統(tǒng)。Romfs是一種只讀文件系統(tǒng)。起初,設(shè)計(jì)它的目的是在啟動(dòng)盤等場(chǎng)合下,提供一個(gè)比普通文件系統(tǒng)(如功能強(qiáng)大的ext2)更加節(jié)省空間的文件系統(tǒng)。空間的節(jié)省來(lái)自于兩個(gè)方面:首先,內(nèi)核支持romfs文件系統(tǒng)比支持ext2文件系統(tǒng)需要更少的代碼;其次,romfs文件系統(tǒng)相對(duì)簡(jiǎn)單,在建立文件系統(tǒng)超級(jí)塊(Superglock)時(shí),需要更少的存儲(chǔ)空間。romfs文件系統(tǒng)不支持動(dòng)態(tài)擦寫保存,對(duì)于系統(tǒng)需要?jiǎng)討B(tài)保存的數(shù)據(jù),可采用虛擬RAM盤的方法處理(RAM盤將采用ext2文件系統(tǒng))。3.2構(gòu)造潛入式Linux系統(tǒng)3.2.1構(gòu)建嵌入式Linux系統(tǒng)的幾個(gè)關(guān)鍵問(wèn)題一個(gè)小型的嵌入式Linux系統(tǒng)需要具備3個(gè)基本元素:引導(dǎo)工具、Linux微內(nèi)核(由內(nèi)存管理、進(jìn)程管理和實(shí)物處理構(gòu)成)及初始化進(jìn)程。若想讓它做些什么且繼續(xù)保持小型化,還須具備:硬件驅(qū)動(dòng)程序,提供所需要功能的一個(gè)或多個(gè)應(yīng)用程序。若需要增加功能,或許需要:一個(gè)文件系統(tǒng)(也許在ROM或RAM中)、TCP/IP網(wǎng)絡(luò)協(xié)議棧及一個(gè)磁盤,用于存放半易失數(shù)據(jù)和提供交換能力。由此可見,構(gòu)造一個(gè)嵌入式Linux系統(tǒng),關(guān)鍵是解決以下幾個(gè)問(wèn)題。如何引導(dǎo)
當(dāng)一個(gè)微處理器第一次啟動(dòng)時(shí),它開始在預(yù)先設(shè)置的地址上執(zhí)行指令。通常在那里有一些只讀內(nèi)存,包括初始化或引導(dǎo)代碼。在PC上,這就是BIOS。BIOS首先執(zhí)行一些低水平的CPU初始化其他硬件的配置,接著辨認(rèn)哪個(gè)磁盤里有操作系統(tǒng),把操作系統(tǒng)復(fù)制到RAM,并且轉(zhuǎn)向它。在PC上運(yùn)行的Linux就是依靠PC的BIOS來(lái)提供相關(guān)配置和加載OS功能的。
在一個(gè)嵌入式系統(tǒng)中,處于經(jīng)濟(jì)性、價(jià)格方面的考慮,通常沒(méi)有BIOS。這就需要開發(fā)者自行提供完成這些工作所需要的程序,這就是所需要的開機(jī)啟動(dòng)代碼。幸運(yùn)的是,潛入式系統(tǒng)的啟動(dòng)代碼不需要像PCBIOS引導(dǎo)程序那樣靈活,因?yàn)樗ǔV豁毺幚硪恍┯布呐渲?。因此啟?dòng)代碼只是一個(gè)指令清單,將固定的數(shù)字賽到硬件的寄存器中去。這個(gè)代碼很簡(jiǎn)單,也很枯燥,然而卻非常關(guān)鍵,因此這些數(shù)值要與硬件相符,而且要按照指定的順序進(jìn)行。嵌入式系統(tǒng)中啟動(dòng)代碼通常放在Flash或EPROM芯片上。具體如何實(shí)現(xiàn),要根據(jù)目標(biāo)硬件和工具來(lái)定。一種常用的方法是,把Flash或EPROM芯片插入EPROM或Flash燒制器,把啟動(dòng)代碼燒入芯片,然后將芯片插入目標(biāo)板插座,這種方法要求目標(biāo)上配有插座。另一種方法是通過(guò)JTAG界面,一些芯片有JTAG界面,可用來(lái)對(duì)芯片進(jìn)行進(jìn)行編程,這樣芯片就可以被焊在主板上。是否需要虛擬內(nèi)存
標(biāo)準(zhǔn)Linux采用虛擬存儲(chǔ)器技術(shù)來(lái)管理內(nèi)存,其優(yōu)點(diǎn)是提供了比計(jì)算機(jī)系統(tǒng)實(shí)際物理內(nèi)存大得多的內(nèi)存空間。這樣編程人員在編程時(shí),勿需考慮計(jì)算機(jī)中物理內(nèi)存的實(shí)際容量。當(dāng)然它也存在缺點(diǎn),虛擬內(nèi)存管理需要通過(guò)內(nèi)存管理單元MMU將虛擬地址轉(zhuǎn)換為物理地址。其中的地址轉(zhuǎn)換表和其他一些數(shù)據(jù)結(jié)構(gòu)占據(jù)了內(nèi)存空間,這樣留給編程人員的內(nèi)存空間就減少了;同時(shí)地址轉(zhuǎn)換增加了每一條指令的執(zhí)行時(shí)間。
在嵌入式系統(tǒng)中,虛擬內(nèi)存管理并無(wú)用武之地;同時(shí)在嵌入式實(shí)時(shí)系統(tǒng)中,它可能會(huì)帶來(lái)無(wú)法控制的時(shí)間問(wèn)題。但明智的做法并不是消除內(nèi)核中的虛擬內(nèi)存代碼,基于兩點(diǎn)原因:一是消除它很費(fèi)事;二是它支持共享代碼,多個(gè)進(jìn)程可以共享某一軟件的同一拷貝。因此,可保留這段代碼,同時(shí)只需將交換空間的大小簡(jiǎn)單地設(shè)置為零,就可以關(guān)掉虛擬內(nèi)存的調(diào)用功能。此后,如果用戶寫的程序比實(shí)際內(nèi)存大,系統(tǒng)就會(huì)當(dāng)作用盡了交換空間來(lái)處理。這個(gè)程序?qū)⒉粫?huì)運(yùn)行,或者malloc將會(huì)失靈。文件系統(tǒng)選擇
許多嵌入式系統(tǒng)沒(méi)有磁盤或者文件系統(tǒng),Linux不需要它們也能運(yùn)行。這種情況下,應(yīng)用程序任務(wù)可與內(nèi)核一起編寫,并且在引導(dǎo)時(shí)作為一個(gè)映像加載。對(duì)于簡(jiǎn)單的系統(tǒng)來(lái)說(shuō),這足夠了,但缺乏靈活性。實(shí)際上,許多商業(yè)性嵌入式操作系統(tǒng)提供文件系統(tǒng)作為選項(xiàng)。Linux提供MS-DOS-Compatible以及其他功能更強(qiáng)大的文家年系統(tǒng)。
文件系統(tǒng)可放在傳統(tǒng)的磁盤驅(qū)動(dòng)器、FlashMemory或其他類似的介質(zhì)上。如果用于暫時(shí)保存文件,一個(gè)小RAM盤就足夠了,F(xiàn)lashMemory通常是這樣保存文件系統(tǒng)的:FlashMemory杯分割成塊,其中有一塊是黨CPU啟動(dòng)運(yùn)行時(shí)的引導(dǎo)塊,里面存放Linux引導(dǎo)代碼,剩余的Flash可用作文件系統(tǒng)。Linux內(nèi)核有兩種加載方式:一是把內(nèi)核的可執(zhí)行映像存儲(chǔ)到Flash的一個(gè)獨(dú)立部分,系統(tǒng)啟動(dòng)時(shí),從Flash的某個(gè)地址開始逐句執(zhí)行;另一種方式是把內(nèi)核的壓縮文件放在Flash上,系統(tǒng)啟動(dòng)時(shí)通過(guò)引導(dǎo)代碼把內(nèi)核壓縮文件從Flash復(fù)制到RAM里,解壓執(zhí)行。因?yàn)镽AM的存取速度高于Flash,所以后一種方式的運(yùn)行速度更高一些,標(biāo)準(zhǔn)Linux就是采用這種方式。消除潛入式Linux系統(tǒng)對(duì)磁盤的依賴
標(biāo)準(zhǔn)Linux內(nèi)核通常主流在內(nèi)存中,每一個(gè)應(yīng)用程序都是從磁盤運(yùn)行到內(nèi)存上執(zhí)行。當(dāng)程序結(jié)束后,它所占的內(nèi)存被釋放,程序就被卸載了。在一個(gè)嵌入式系統(tǒng)中,可能沒(méi)有磁盤。有兩條途徑可以消除對(duì)磁盤的依賴,這要看系統(tǒng)的復(fù)雜性和硬件的設(shè)計(jì)如何:
在一個(gè)簡(jiǎn)單的系統(tǒng)中,當(dāng)系統(tǒng)啟動(dòng)后,內(nèi)核和所有的應(yīng)用程序都在內(nèi)存里。這是大多數(shù)傳統(tǒng)潛入式系統(tǒng)的工作模式,它同樣也被Linux支持。
有了Linux,就有了第二種可能性,因?yàn)長(zhǎng)inux有能力加載和卸載程序,一個(gè)嵌入式系統(tǒng)可利用它來(lái)節(jié)省內(nèi)存。在一個(gè)典型的具有FlashMemory的嵌入式系統(tǒng)中,F(xiàn)lashMemory上裝有文件系統(tǒng),所有的程序都以文件的形式存儲(chǔ)在Flash文件中,需要時(shí)裝入內(nèi)存。這種動(dòng)態(tài)的、根據(jù)需要加載的能力是支持其他一系列功能的重要特征。
它使初始化代碼在系統(tǒng)引導(dǎo)后被釋放。Linux有很多內(nèi)核外運(yùn)行的公用程序,這些程序通常在初始化時(shí)運(yùn)行一次,以后不再運(yùn)行;而且,這些公用程序可以它們共有的方式一個(gè)接一個(gè)地按順序運(yùn)行。這樣,相同的內(nèi)存空間可被反復(fù)使用,以“召入”每一個(gè)程序,達(dá)到節(jié)省內(nèi)存空間的目的。
如果Linux可加載模塊的功能包括在內(nèi)核里,那么驅(qū)動(dòng)程序和應(yīng)用程序就都可以被加載。它可檢查硬件環(huán)境,并且為硬件裝上相應(yīng)的軟件,這就消除了用一個(gè)程序占用很多FlashMemory來(lái)處理多種硬件所引起的復(fù)雜性。
軟件的升級(jí)更模塊化。可在系統(tǒng)運(yùn)行時(shí),在Flash上升級(jí)應(yīng)用程序和可加載的驅(qū)動(dòng)程序。配置信息和運(yùn)行時(shí)間參數(shù)可作為數(shù)據(jù)文件存儲(chǔ)在Flash上。3.2.1構(gòu)建嵌入式Linux系統(tǒng)的關(guān)鍵步驟嵌入式應(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ò)串口建立連接通信。建立交叉開發(fā)環(huán)境
在軟件開發(fā)環(huán)境建立方面,由于uClinux及相關(guān)工具集都是開放源碼項(xiàng)目,所以大多數(shù)軟件都可以從網(wǎng)站上下載獲得。首先要在宿主機(jī)上安裝標(biāo)準(zhǔn)Linux發(fā)行版,比如RedHatLinux,接下來(lái)就是建立交叉開發(fā)環(huán)境。安裝交叉編譯工具
uClinux編譯工具中的交叉編譯器可對(duì)源代碼包括內(nèi)核進(jìn)行編譯,以適應(yīng)不同的嵌入式應(yīng)用場(chǎng)合。編譯工具包中除了交叉編譯器,還有鏈接器、匯編器以及一些為了方便開發(fā)的二進(jìn)制處理工具,包括生成靜態(tài)庫(kù)工具、二進(jìn)制碼察看工具及二進(jìn)制格式轉(zhuǎn)換工具。這些都要安裝在宿主機(jī)上。安裝uClinux內(nèi)核
利用已安裝的交叉編譯器編譯生成與運(yùn)行目標(biāo)機(jī)上的uClinux內(nèi)核。與標(biāo)準(zhǔn)Linux相同的是,uClinux內(nèi)核可以以配置的方式選擇需要安裝的模塊,而增加系統(tǒng)的靈活性。安裝應(yīng)用程序
用交叉編譯器編譯uC-libc和uC-libm源碼,聲稱libc.a應(yīng)用程序庫(kù)和libm.a數(shù)學(xué)庫(kù)。安裝其他工具
用GCC編譯elf2flt源碼,聲稱格式轉(zhuǎn)換工具elf2flt。用GCC編譯genromfs源碼,得到生成romfs的工具genromfs。經(jīng)過(guò)以上的準(zhǔn)備工作之后,下面要針對(duì)特定應(yīng)用所需要的設(shè)備編寫或改造設(shè)備驅(qū)動(dòng)程序。有如果用戶對(duì)系統(tǒng)實(shí)時(shí)性,特別是對(duì)硬實(shí)時(shí)有特殊要求,uClinux可以加入RT-linux的實(shí)時(shí)模塊。3.3uClinux在ARMulator的移植盡管uClinux很小,但它支持Linux2.6內(nèi)核約定的全部的特性,包括內(nèi)核優(yōu)先級(jí)特性以及許多的文件系統(tǒng),設(shè)備驅(qū)動(dòng)。為L(zhǎng)inux約定設(shè)備驅(qū)動(dòng)端口是容易實(shí)現(xiàn)的。幾乎所有的代碼不需要改變就可以編譯,除了從虛擬地址到物理的內(nèi)存鏡像外。
下面將介紹如何將uClinux2.6.5移植到基于GDB的ARMulator上。從uC站點(diǎn)上下載uClinux發(fā)布包
,本文以u(píng)Clinux-dist.20040408.tar.gz為例。/download/linux-2.6.5-hsc2.patch.gz和/pub/linux/kernel/v2.6/linux-2.6.5.tar.bz2分別下載linux-2.6.5-hsc2.patch.gz和內(nèi)核linux2.6.5的源文件。從站點(diǎn)上更新的ARM-ELF工具鏈來(lái)編譯內(nèi)核,本文以arm-elf-tools-20040427.sh為例。構(gòu)造虛擬硬件環(huán)境ARMulator(ARM仿真)安裝工具鏈。以root身份登陸宿主機(jī)下的Llinux系統(tǒng),然后在終端中進(jìn)入存放工具鏈的所在目錄,然后輸入/bin/sh
arm-elf-tools-20040427.sh解壓uClinux發(fā)布包
并將linux2.6.5源文件和補(bǔ)丁解壓到相同目錄下。修改vendors/GDB/ARMulator目錄下面的ARMulator默認(rèn)的配置文件rc
修改后內(nèi)容如下:hostnameGDB-ARMulator/bin/expand/etc/ramfs.img/dev/ram1mount-tprocproc/procmount-text2/dev/ram1/varmkdir/var/tmpmkdir/var/logmkdir/var/runmkdir/var/lockmkdir/var/emptycat/etc/m
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 科技驅(qū)動(dòng)下的客戶服務(wù)質(zhì)量提升報(bào)告
- 2025年互聯(lián)網(wǎng)廣告效果評(píng)估與分析服務(wù)合同
- 高中生綜合素質(zhì)的自我陳述報(bào)告范文
- 疫情后時(shí)代小微餐飲企業(yè)的復(fù)蘇與市場(chǎng)策略研究報(bào)告
- 2025年上海市商品房產(chǎn)購(gòu)銷合同范文(2篇)
- GB/T 20991-2024足部防護(hù)鞋的測(cè)試方法
- 二手房房屋買賣合同正規(guī)版本
- 2024年CBZ-5-苯基-L-半胱氨酸項(xiàng)目項(xiàng)目投資申請(qǐng)報(bào)告代可行性研究報(bào)告
- RNF5-agonist-1-生命科學(xué)試劑-MCE-3083
- Acremine-F-生命科學(xué)試劑-MCE-8674
- 廣東省茂名市電白區(qū)2024-2025學(xué)年七年級(jí)上學(xué)期期末質(zhì)量監(jiān)測(cè)生物學(xué)試卷(含答案)
- 《教育強(qiáng)國(guó)建設(shè)規(guī)劃綱要(2024-2035年)》全文
- 山東省濱州市2024-2025學(xué)年高二上學(xué)期期末地理試題( 含答案)
- 2025年河南洛陽(yáng)市孟津區(qū)引進(jìn)研究生學(xué)歷人才50人歷年高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2025年度軍人軍事秘密保護(hù)保密協(xié)議與信息安全風(fēng)險(xiǎn)評(píng)估合同3篇
- 蛋雞生產(chǎn)飼養(yǎng)養(yǎng)殖培訓(xùn)課件
- 數(shù)字化轉(zhuǎn)型中的職業(yè)能力重構(gòu)
- 運(yùn)用PDCA降低住院患者跌倒-墜床發(fā)生率
- 2025屆高中數(shù)學(xué)一輪復(fù)習(xí)專練:橢圓(含解析)
- 立春氣象與生活影響模板
- 中國(guó)服裝零售行業(yè)發(fā)展環(huán)境、市場(chǎng)運(yùn)行格局及前景研究報(bào)告-智研咨詢(2025版)
評(píng)論
0/150
提交評(píng)論