實時嵌入式操作系統(tǒng)設(shè)計論文_第1頁
實時嵌入式操作系統(tǒng)設(shè)計論文_第2頁
實時嵌入式操作系統(tǒng)設(shè)計論文_第3頁
實時嵌入式操作系統(tǒng)設(shè)計論文_第4頁
實時嵌入式操作系統(tǒng)設(shè)計論文_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

畢業(yè)設(shè)計(論文)第 PAGEII頁畢業(yè)設(shè)計(論文)設(shè)計(論文)題目:實時嵌入式操作系統(tǒng)的設(shè)計學生姓名學生學號 專業(yè)班級 指導老師 年5月29日實時嵌入式操作系統(tǒng)的設(shè)計摘要隨著微處理器的發(fā)展,種類繁多、價格低廉、結(jié)構(gòu)小巧的CPU和外設(shè)連接,提供了穩(wěn)定、可靠的硬件架構(gòu)?,F(xiàn)在嵌入式系統(tǒng)發(fā)展的瓶頸在軟件方面,尤其是操作系統(tǒng)的“嵌入式”化。由于Linux源碼的開放性、簡練、多任務(wù)、易移植、成本低等特性,成為諸多研究與應(yīng)用選擇的對象。隨著2.6內(nèi)核的發(fā)布,Linux向現(xiàn)有主流的實時操作系統(tǒng)提出了更大的挑戰(zhàn),勢必能成為更優(yōu)秀的嵌入式操作系統(tǒng)。本人一直以來都對Linux操作系統(tǒng)很感興趣,并結(jié)合本專業(yè),對Linux應(yīng)用于嵌入式實時環(huán)境進行了一定的研究。深入探討了面向嵌入式實時環(huán)境的Linux系統(tǒng)的體系結(jié)構(gòu)。論文首先概述了嵌入式系統(tǒng)及實時系統(tǒng)的發(fā)展情況,然后介紹Linux在實時領(lǐng)域的相關(guān)研究,其次講述了嵌入式Linux系統(tǒng)的構(gòu)造,最后描述了系統(tǒng)測試的策略,并就下一步可繼續(xù)進行的工作進行了展望。關(guān)鍵詞: Linux;進程;實時系統(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嵌入式實時系統(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實時嵌入式系統(tǒng)概況 31.2.1什么是實時嵌入式系統(tǒng) 31.2.2實時嵌入式操作系統(tǒng) 42Linux作為實時系統(tǒng)的分析 62.1Linux內(nèi)核體系結(jié)構(gòu) 62.2Linux進程管理 72.2.1進程描述符 82.2.2進程調(diào)度 132.2.2搶占 162.2.3調(diào)度器的實時性能 183構(gòu)造嵌入式Linux系統(tǒng) 203.1uClinux結(jié)局方案 203.2構(gòu)造潛入式Linux系統(tǒng) 213.2.1構(gòu)建嵌入式Linux系統(tǒng)的幾個關(guān)鍵問題 213.2.1構(gòu)建嵌入式Linux系統(tǒng)的關(guān)鍵步驟 243.3uClinux在ARMulator的移植 254測試方案 28總結(jié) 29致謝 30參考文獻 311嵌入式實時系統(tǒng)概況1.1嵌入式系統(tǒng)概況1.1.1關(guān)于嵌入式系統(tǒng)嵌入式系統(tǒng)在現(xiàn)代人的日常生活中已經(jīng)無處不在(如圖1-1),而且正在越來越深地介入我們的生活、工作甚至娛樂。圖1-1日常生活中的嵌入式系統(tǒng)從幾十年前出現(xiàn)的計算機開始,人們身邊出現(xiàn)了越來越多的嵌入式系統(tǒng),而Intel公司第一款處理其4004的主要應(yīng)用就是計算器。電話是影響人們生活方式的重要發(fā)明成果之一,作為其核心設(shè)備的存儲程序控制(SPC)電話交換機早在上個世紀中后期就已經(jīng)出現(xiàn),電話交換機就是一類典型的實時嵌入式系統(tǒng)。除通訊、國防、航空航天和醫(yī)療領(lǐng)域以外,汽車工業(yè)也是嵌入式系統(tǒng)使用最早的行業(yè)之一。當今的每部中高檔汽車上都至少有幾套甚至幾十套嵌入式系統(tǒng)在協(xié)調(diào)工作,控制著汽車的轉(zhuǎn)向、液壓、制動、空調(diào)、ABS等等一系列功能,其中大多數(shù)都是實時系統(tǒng)。今年來,嵌入式系統(tǒng)以消費電子設(shè)備的形態(tài)大量進入人們的生活:移動電話、數(shù)碼相機、數(shù)字攝像機、游戲機、電子辭典、PDA(PersonalDigitalAssistant,個人數(shù)字助理)、MP3播放器、微波爐、空調(diào)、數(shù)字電視、DVD播放機、傳真機等[1]。Internet是近年來對人們生活方式影響最大的技術(shù)成果。但為大多數(shù)人所忽略的是,Internet實際上是有史以來世界上最大的嵌入式系統(tǒng)集合。Internet上的高端路由器、ATM交換機、以太網(wǎng)交換機、網(wǎng)關(guān)等核心設(shè)備都是實時處理能力很強的嵌入式系統(tǒng)。1.1.2嵌入式系統(tǒng)的基本特征從以上那些耳熟能詳?shù)那度胧皆O(shè)備中(其中某些是實時嵌入式設(shè)備),我們應(yīng)該能感覺到嵌入式系統(tǒng)的一些基本特征:嵌入式系統(tǒng)由智能單元(即微處理器,有時存在多個)控制,因而是計算機系統(tǒng)。但因形態(tài)多樣,多數(shù)情況下此特征為人們所忽略。嵌入式系統(tǒng)所提供的功能通常帶有針對性,大多是專用系統(tǒng)。與桌面系統(tǒng)不同,嵌入式系統(tǒng)一般不對用戶提供再開發(fā)環(huán)境,用戶與系統(tǒng)交互的唯一端口就是系統(tǒng)提供給用戶的最終應(yīng)用。針對某些特殊應(yīng)用,如航天飛機、衛(wèi)星、飛機等,嵌入式系統(tǒng)常常需要很高的可靠性和長時間無人值守的工作能力。這一點對操作系統(tǒng)得要求至關(guān)重要。緊湊性要求明顯(因系統(tǒng)而異)?;诔杀尽Ⅲw積、功耗和性價比等因素考慮,許多嵌入式系統(tǒng)通常不追求高速而功耗大的處理器,采用盡可能少(但夠用)的存儲器。他的軟件(或固件/Firmware)和數(shù)據(jù)通常保存在系統(tǒng)的非易失存儲器上(如Flash)。這些都對操作系統(tǒng)的處理性能和可裁減性有特殊要求。實時性需求。在給定硬件環(huán)境條件下,系統(tǒng)實時性主要依靠操作系統(tǒng)和應(yīng)用軟件保障。1.1.3典型的嵌入式系統(tǒng)信息家電商機引發(fā)全球嵌入式操作系統(tǒng)平臺大戰(zhàn),全球4大操作系統(tǒng)陣營WinCE、PalmOS、EPOC和Linux展開規(guī)格戰(zhàn),各擁有軟件及硬件合作廠商逐鹿信息家電市場的份額。微軟窗口操作系統(tǒng)擁有在個人電腦上的操作系統(tǒng)占有率的優(yōu)勢,使WinCE擁有強大的窗口資源支援。不過PalmOS操作系統(tǒng)擁有全球PDA產(chǎn)品70%的市場占有率;同時獲得3COM、IBM和索尼等跨國公司的支持。EPOC是發(fā)展自歐洲的操作系統(tǒng)、是由世界上最大的3家移動電話廠商諾基亞、愛立信和摩托羅拉所共同開發(fā)、整合組成新公司,開發(fā)出來的新操作系統(tǒng);在3大電話廠商的合作下,EPOC市場潛力很大,且占有率高,但應(yīng)用功能以手機為主,目前并不開放授權(quán)。此外,在3大主流操作系統(tǒng)品牌外,Linux也將是今后一股強勁的力量;由于Linux開放源碼,經(jīng)過這些年的發(fā)展,已經(jīng)成為一個健壯的可靠的高性能的操作系統(tǒng)。愈來愈多的嵌入式系統(tǒng)設(shè)計員發(fā)現(xiàn)Linux可以成為一個優(yōu)秀的嵌入式操作系統(tǒng)。而Linux的最大的優(yōu)勢還在于它是一個開放的操作系統(tǒng)。由于Linux開放源碼,操作系統(tǒng)的一切對用戶都是透明的,用戶可以最大限度地控制系統(tǒng)開發(fā)的進度和造價。在開發(fā)過程中遇到的各種各樣的硬件設(shè)備,可以方便地在網(wǎng)上找到這些設(shè)備的驅(qū)動程序,得到支持。Linux內(nèi)置網(wǎng)絡(luò)支持,用戶可以輕松地使自己的嵌入式具有網(wǎng)絡(luò)功能。Linux是模塊化的操作系統(tǒng),提供了優(yōu)秀的可縮放功能,用戶可以方便地刪除不需要的模塊,大多數(shù)嵌入式系統(tǒng)對操作系統(tǒng)的體積非常敏感,Linux的可以根據(jù)自己的需要,選擇特定的功能模塊,自主地搭建嵌入式操作系統(tǒng)。Linux支持絕大多數(shù)CPU,包括Intel、MIPS、ASIC、ALPHA、68K、POWERPC等。這使Linux幾乎可以嵌入到各種硬件設(shè)備上。成為各家廠商極力發(fā)展的操作系統(tǒng),加上其核心小,潛力可觀。1.2實時嵌入式系統(tǒng)概況1.2.1什么是實時嵌入式系統(tǒng)嵌入式系統(tǒng)不都是實時系統(tǒng)。比如掌上電腦、電子辭典等,它們具備嵌入式系統(tǒng)的基本特征,但基本沒有實時性要求。而實時性系統(tǒng)也不都是嵌入式系統(tǒng)。當我們將個人電腦裝上實時操作系統(tǒng)并用于工業(yè)生產(chǎn)線實時控制時,該系統(tǒng)并不具備被嵌入式特征,因此我們可以說實時嵌入式系統(tǒng)是嵌入式系統(tǒng)與實時系統(tǒng)的交集(如圖1-2)。但一般而言,嵌入式系統(tǒng)中有相當大的比例是實時系統(tǒng)。[2]圖1-2嵌入式實時系統(tǒng)的邊界與非實時系統(tǒng)不同之處在于,實時系統(tǒng)對外部事件的響應(yīng)有時間要求,即要在給定時間內(nèi)完成事件的識別、處理,并給出正確結(jié)果。外部事件可分為兩類,即同步時間(SynchronousEvents)和異步事件(AsynchronousEvents)。同步事件是周期性的,系統(tǒng)可以預(yù)見下一次同類事件發(fā)生的時刻;異步事件是非周期的,事件發(fā)生的事件不可預(yù)測。實時操作系統(tǒng)必須有能力處理這兩類事件。Deadline是實時系統(tǒng)追求的最重要的指標。但不同的實時系統(tǒng)得Deadline的要求不同,并據(jù)此將實時系統(tǒng)分為兩類:HardReal-time(硬實時)和SoftReal-time(軟實時)。1.2.2實時嵌入式操作系統(tǒng)同樣作為操作系統(tǒng),實時嵌入式操作系統(tǒng)與通常意義上的操作系統(tǒng)在基本功能方面應(yīng)該是一致的,但必然存在明顯差異。首先,實時嵌入式操作系統(tǒng)負責實時嵌入式系統(tǒng)的所有軟硬件資源的分配、調(diào)度工作、控制和協(xié)調(diào)并發(fā)活動,如任務(wù)調(diào)度、內(nèi)存管理、同步機制、異常和中段處理、任務(wù)間通信等,具有一般操作系統(tǒng)的基本功能:同時它也必須具有其實時處理和嵌入式系統(tǒng)特征。與通用操作系統(tǒng)相比,實時嵌入式操作系統(tǒng)具有如下一些特點[3]:實時性。大多數(shù)嵌入式系統(tǒng)工作在實時性要求很高的環(huán)境中,對外部事件的響應(yīng),包括數(shù)據(jù)的獲取、處理和數(shù)據(jù)的輸出都必須在deadline規(guī)定時間內(nèi)完成。這就要求實時嵌入式操作系統(tǒng)必須將實時性作為一個重要指標。小型化、可裁減。嵌入式系統(tǒng)所能提供的資源有限,所以實時嵌入式操作系統(tǒng)必須做得小巧,以滿足前入式系統(tǒng)的硬件限制,同時必須能夠根據(jù)應(yīng)用的要求進行裁減,去除多余的部分,或者簡化相應(yīng)得模塊。強穩(wěn)定性。與桌面系統(tǒng)不同,大多數(shù)嵌入式系統(tǒng)一旦開始運行就不需要人過多的干預(yù)。在這種條件下,要求作為系統(tǒng)資源總管的操作系統(tǒng)具有較高的穩(wěn)定性。固化代碼。在嵌入式系統(tǒng)中,操作系統(tǒng)與應(yīng)用軟件代碼通常被固化在嵌入式系統(tǒng)的ROM中。目前輔助存儲器(如磁盤)在嵌入式系統(tǒng)中很少使用,因此,實時嵌入式操作系統(tǒng)的文件管理功能應(yīng)該能夠很容易裁減,取而代之的是各種內(nèi)存文件系統(tǒng)。弱交互性。除消費類電子設(shè)備以外,大多數(shù)嵌入式系統(tǒng)的工作過程不需要人的干預(yù)。因此多數(shù)實時嵌入式操作系統(tǒng)所提供給用戶操作的接口相對簡單,主要通過系統(tǒng)調(diào)用命令向用戶程序提供服務(wù)。專業(yè)化強。每一種實時嵌入式操作系統(tǒng)通常面向特定類型或幾種相近類型應(yīng)用。某些操作系統(tǒng)會根據(jù)不同的應(yīng)用對象采用不同的模塊搭配。有些操作系統(tǒng)甚至是自行研發(fā)的內(nèi)部產(chǎn)品。值得注意的是,隨著各種各樣的實時嵌入式操作系統(tǒng)的出現(xiàn),人們有必要對實時嵌入式系統(tǒng)提供的借口進行約定,從而為嵌入式應(yīng)用軟件的設(shè)計者提供統(tǒng)一的服務(wù)借口,例如POSIX(PortableOperationSystemInterface,可移植操作系統(tǒng)接口)有可移植性和平臺無關(guān)性。[4]通過上面的敘述,我們知道實時性能使評價實時嵌入式操作系統(tǒng)的重要指標,但不是唯一的指標。完善的操作系統(tǒng)應(yīng)提供完善的功能和豐富的開發(fā)工具,如文件管理、設(shè)備支持、網(wǎng)絡(luò)支持、人機交互、GUI、API豐富度、硬件無關(guān)設(shè)計,以及編譯環(huán)境、調(diào)試環(huán)境、多種處理器支持、穩(wěn)定度、可裁減性、可擴充性、開放接口以及維護等諸多方面。而Linux操作系統(tǒng)在這些方面都有相當出色的表現(xiàn)。2Linux作為實時系統(tǒng)的分析Linux可以說是世界上變化最快的操作系統(tǒng),幾乎每個月都會有新的內(nèi)核升級版本問世,這也是Linux進步如此神速的主要原因。根據(jù)功能不同,Linux內(nèi)核的模塊可基本劃分為進程管理、內(nèi)存管理、網(wǎng)絡(luò)管理、文件系統(tǒng)與進程通信幾部分。實時可靠性是嵌入式應(yīng)用較為普遍的要求,盡管Linux已發(fā)展到2.6版本,但它仍不是一個真正的實時操作系統(tǒng),但其改進的特性能夠滿足響應(yīng)需求。Linux2.6已經(jīng)在內(nèi)核主體中加入了提高中斷性能和調(diào)度響應(yīng)時間的改進,其中有三個最顯著的改進:采用可搶占內(nèi)核、更加有效的調(diào)度算法以及同步性的提高[5]。2.1Linux內(nèi)核體系結(jié)構(gòu)Linux內(nèi)核主要由五個子系統(tǒng)組成:進程調(diào)度,內(nèi)存管理,虛擬文件系統(tǒng),網(wǎng)絡(luò)接口,進程間通信。[6]1進程調(diào)度(SCHED):控制進程對CPU的訪問。當需要選擇下一個進程運行時,由調(diào)度程序選擇最值得運行的進程。可運行進程實際上是僅等待CPU資源的進程,如果某個進程在等待其它資源,則該進程是不可運行進程。Linux使用了比較簡單的基于優(yōu)先級的進程調(diào)度算法選擇新的進程。2內(nèi)存管理(MM)允許多個進程安全的共享主內(nèi)存區(qū)域。Linux的內(nèi)存管理支持虛擬內(nèi)存,即在計算機中運行的程序,其代碼,數(shù)據(jù),堆棧的總量可以超過實際內(nèi)存的大小,只是把當前使用的程序塊保留在內(nèi)存中,其余的程序塊則保留在中。必要時,操作系統(tǒng)負責在磁盤和內(nèi)存間交換程序塊。內(nèi)存管理從邏輯上分為無關(guān)部分和硬件有關(guān)部分。硬件無關(guān)部分提供了進程的映射和邏輯內(nèi)存的對換;硬件相關(guān)的部分為內(nèi)存管理硬件提供了虛擬接口[10]。3虛擬文件系統(tǒng)(VirtualFileSystem,VFS)隱藏了各種硬件的具體細節(jié),為所有的設(shè)備提供了統(tǒng)一的接口,VFS提供了多達數(shù)十種不同的文件系統(tǒng)。虛擬文件系統(tǒng)可以分為邏輯文件系統(tǒng)和設(shè)備程序。邏輯文件系統(tǒng)指Linux所支持的文件系統(tǒng),如ext2,fat等,設(shè)備驅(qū)動程序指為每一種硬件控制器所編寫的設(shè)備驅(qū)動程序模塊。4網(wǎng)絡(luò)接口(NET)提供了對各種網(wǎng)絡(luò)標準的存取和各種網(wǎng)絡(luò)硬件的支持。網(wǎng)絡(luò)接口可分為網(wǎng)絡(luò)協(xié)議和網(wǎng)絡(luò)驅(qū)動程序。網(wǎng)絡(luò)協(xié)議部分負責實現(xiàn)每一種可能的網(wǎng)絡(luò)傳輸協(xié)議。網(wǎng)絡(luò)設(shè)備驅(qū)動程序負責與硬件設(shè)備通訊,每一種可能的硬件設(shè)備都有相應(yīng)的設(shè)備驅(qū)動程序。5進程間通訊(IPC)支持進程間各種通信機制。圖2-1Linux內(nèi)核的五個子系統(tǒng)如圖2-1處于中心位置的進程調(diào)度,所有其它的子系統(tǒng)都依賴它,因為每個子系統(tǒng)都需要掛起或恢復進程。一般情況下,當一個進程等待硬件操作完成時,它被掛起;當操作真正完成時,進程被恢復執(zhí)行。例如,當一個進程通過網(wǎng)絡(luò)發(fā)送一條消息時,網(wǎng)絡(luò)接口需要掛起發(fā)送進程,直到硬件成功地完成消息的發(fā)送,當消息被成功的發(fā)送出去以后,網(wǎng)絡(luò)接口給進程返回一個代碼,表示操作的成功或失敗。其他子系統(tǒng)以相似的理由依賴于進程調(diào)度。2.2Linux進程管理如果說操作系統(tǒng)是開發(fā)者所依賴的框架,那么,進程就是由這個框架所承擔和管理的基本或從單元。進程是一個動態(tài)的實用系統(tǒng)資源、處于活動狀態(tài)的程序。Linux是一個多任務(wù)操作程序,程序調(diào)度器使用合適的調(diào)用算法來調(diào)用進程。Linux進程管理由進程控制塊、進程調(diào)度、中斷處理、任務(wù)隊列、定時器、bottomhalf隊列、系統(tǒng)調(diào)用、進程通信等部分組成。[7]一個程序可啟動多次,它的每個運行副本都有自己的進程。進程的生命周期分為進程的產(chǎn)生、執(zhí)行和結(jié)束三個部分。2.2.1進程描述符在內(nèi)核中,進程描述符是一個名為task_struct的結(jié)構(gòu)體,用于保存進程的屬性和其他信息,我們可以在這個結(jié)構(gòu)體中找到與進程有關(guān)的所有內(nèi)核信息。在其生命周期內(nèi),進程要與內(nèi)核的方方面面,“諸如內(nèi)存管理和調(diào)度”等打交道,因此,除了UNIX進程的標準屬性外,進程描述符也保存了在上述交互過程中的相關(guān)信息。內(nèi)核用循環(huán)雙向鏈表task_list存放所有進程描述符,同時借助全局變量current保存當前運行進程的task_struct。數(shù)組task包含指向系統(tǒng)中所有task_struct結(jié)構(gòu)的指針。系統(tǒng)中的最大進程數(shù)目受task數(shù)組大小的限制,默認值一般為512。創(chuàng)建新進程時,Linux將從系統(tǒng)內(nèi)存中分配一個task_struct結(jié)構(gòu),并將其加入task數(shù)組。操作系統(tǒng)初始化后,建立init進程,它創(chuàng)建第一個task_struct數(shù)據(jù)結(jié)構(gòu)INIT_TASK。當前運行進程的結(jié)構(gòu)用current指針來表示。在進程生命周期中,進程描述符必須保存的信息的類型有[8]:進程的屬性進程間的關(guān)系進程的內(nèi)存空間文件管理信號量管理進程的可信度資源限制與調(diào)度相關(guān)的域下面我們來了解一些Task_struct結(jié)構(gòu)中與嵌入式開發(fā)相關(guān)的域。進程狀態(tài)(volatilelongstate)進程狀態(tài)定義有如下幾種://正在運行的進程或在Running隊列中準備運行的進程#defineTASK_RUNNING 0//處于等待隊列中的進程,等資源有效時喚醒進入就緒隊列run-queue#defineTASK_INTERRUPTIBLE 1//處于等待隊列中的進程,等資源有效時喚醒,但不可被其他進程中斷#defineTASK_UNINTERRUPTIBLE 2//進程暫停,通過其他進程才能喚醒#defineTASK_STOPPED 4//進程已經(jīng)被殺死,但父進程還沒有調(diào)用sys_wait()#defineTASK_ZOMBIE 8//僵死狀態(tài)的進程,進程已經(jīng)結(jié)束運行且釋放大部分資源,但未釋放其進程塊#defineTASK_DEAD 16進程狀態(tài)轉(zhuǎn)換如圖2-2所示,用戶進程由do_fork()函數(shù)創(chuàng)建,它也是fork系統(tǒng)調(diào)用的執(zhí)行者。do_fork()創(chuàng)建一個新的進程,繼承父進程現(xiàn)有資源,初始化進程時鐘、信號、時間等數(shù)據(jù)。完成子進程初始化后,父進程將它掛到就緒隊列run-queue,返回子進程的pid。圖2.2Linux進程狀態(tài)轉(zhuǎn)換圖進程創(chuàng)建時的狀態(tài)為TASK_UNINTERRUPTIBLE,在do_fork()結(jié)束前被父進程喚醒后,變?yōu)門ASK_RUNNING。處于TASK_RUNNING狀態(tài)的進程被移到run-queue隊列中,在適當時候由schedule()按CPU調(diào)度算法選中,獲得CPU。獲得CPU而正在運行的進程若申請不到某個資源,則調(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ù)把睡眠進程釋放的CPU分配給run-queue隊列的某個就緒進程。狀態(tài)為TASK_INTERRUPTIBLE的睡眠進程當它申請的資源有效時被喚醒(如wake_up_interruptible()),也可以由信號(signal)或定時中斷喚醒。而狀態(tài)為TASK_UNINTERRUPTIBLE的睡眠進程只有當它申請的資源有效時被喚醒(如wake_up()),不能被信號(signal)、定時中斷喚醒。喚醒后,進程狀態(tài)改為TASK_RUNNING,并進入run-queue隊列。進程執(zhí)行系統(tǒng)調(diào)用sys_exit()或收到SIG_KILL信號而調(diào)用do_exit()時,進程狀態(tài)變?yōu)門ASK_ZOMBIE,釋放所申請資源。同時啟動schedule()把CPU分配給run-queue隊列中其它就緒進程。若進程通過系統(tǒng)調(diào)用設(shè)置PF_SYSTRACE,則在系統(tǒng)調(diào)用返回前,進入syscall_trace(),狀態(tài)變?yōu)門ASK_STOPPED,CPU分配給run-queue隊列中其它就緒進程。只有通過其它進程發(fā)送SIG_KILL或SIG_CONT,才能把TASK_STOPPED進程喚醒。重新進入run-queue隊列。進程優(yōu)先級

intprio,優(yōu)先級,在0~(MAX_PRIO)-1之間取值(MAX_PRIO定義為140),其中0~(MAX_RT_PRIO)-1(MAX_RT_PRIO定義為100)屬于實時進程范圍。在內(nèi)核2.6版本中,動態(tài)優(yōu)先級獨立計算,通過priority_array結(jié)構(gòu)按優(yōu)先級排序,存儲在進程的task_struct中。

intstatic_prio,靜態(tài)優(yōu)先級,與Linux2.4的nice值意義相同,但轉(zhuǎn)換到與prio相同的取值區(qū)間。nice值沿用Linux的傳統(tǒng),在-20~19之間變動,數(shù)值越大,進程的優(yōu)先級越低。nice是用戶可維護的,但僅影響非實時進程的優(yōu)先級。Linux2.6內(nèi)核中不再存儲nice值,而代之以static_prio。進程初始時間片的大小僅取決于進程的靜態(tài)優(yōu)先級,這一點無論是實時進程還是非實時進程都一樣,不過實時進程的static_prio不參與優(yōu)先級計算。

nice與static_prio之間的關(guān)系如下:

static_prio=MAX_RT_PRIO+nice+20prio_array_t*array

它是優(yōu)先級數(shù)組,它將進程優(yōu)先級為序號組成數(shù)組。它也是runqueue結(jié)構(gòu)的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。實時優(yōu)先級

rt_priority給出實時進程的優(yōu)先級,而rt_priority+1000則表示每次獲得CPU后,可使用的時間(按jiffy計算)。實時進程的優(yōu)先級可通過系統(tǒng)調(diào)用sys_sched_setschedule()改變,實際的工作是由setscheduler()完成得。

在Linux2.6內(nèi)核中,候選進程是直接按算法排序的優(yōu)先級隊列數(shù)組中選取出來的,而優(yōu)先級的計算分散到多出進行。進程在適當?shù)臅r機就會計算動態(tài)優(yōu)先級。同時,影響動態(tài)優(yōu)先級的因素集中反映在sleep_avg變量上。只要進程狀態(tài)發(fā)生改變,內(nèi)核就有可能計算并設(shè)置進程的動態(tài)優(yōu)先級。activated

activated表示進程由于某種原因進入就緒態(tài),這一原因會影響到調(diào)度優(yōu)先級的計算。activated有四個值:-1,進程從TASK_UNINTERRUPTIBLE狀態(tài)被喚醒0,默認值,進程原本就處于就緒態(tài)1,進程從TASK_INTERRUPTIBLE狀態(tài)被喚醒,且不在中斷上下文中2,進程從TASK_INTERRUPTIBLE狀態(tài)被喚醒,且在中斷上下文中activated初值為0,在兩個地方修改:一個是在schedule()中,被恢復為0;另一個就是activate_task(),這個函數(shù)由try_to_wake_up()函數(shù)調(diào)用,用于激活休眠狀態(tài)。sleep_avg

進程的平均等待時間(以nanosecond為計算單位),在0到NS_MAX_SLEEP_AVG之間取值,初值為0,相當于進程等待時間與運行時間的差值。sleep_avg所代表的含義比較豐富,既可用于評價該進程的“交互程度”,又可用于表示該進程需要運行的緊迫度。這個值是動態(tài)優(yōu)先級計算的關(guān)鍵因子,sleep_avg越大,計算出來的進程優(yōu)先級也越高(數(shù)值越?。?。

sleep_avg反映了調(diào)度系統(tǒng)的兩種策略:交互式進程優(yōu)先與分時系統(tǒng)的公平共享。time_slice

time_slice變量表示進程的運行時間片剩余大小。進程默認時間片與進程的靜態(tài)優(yōu)先級相關(guān)。在進程創(chuàng)建時,它與父進程平分時間片,在運行過程中遞減,一旦歸零,則按static_prio靜態(tài)優(yōu)先級值重新賦予基準值,并請求調(diào)度。時間片的遞減和重置在時鐘中斷中進行(scheduler_tick()),除此之外,time_slice值主要在進程創(chuàng)建和進程退出的過程中變化。policy

policy可以決定進程的類型,不同類型的進程運行時的調(diào)度策略也不同(例如,分時進程和實時進程的調(diào)度策略不同)。進程的類型及大影響到其調(diào)度優(yōu)先級。2.2.2進程調(diào)度在linux2.6中,采用O(1)調(diào)度算法,調(diào)度器開銷恒定,與當前系統(tǒng)負載無關(guān),實時性能更好。Linux2.4中的就緒隊列是一個簡單的以runqueue_head為頭的雙向鏈表,而在Linux2.6中,每個CPU都將維護一個自己的runqueue結(jié)構(gòu)的就緒隊列,這將大大減少競爭。每個CPU的就緒隊列按時間片是否用完分為兩部分,分別通過active指針和expired指針訪問。[9]Acrive指向時間片沒有用完的、當前可被調(diào)度的就緒進程;expired指向時間片已經(jīng)用完的就緒進程。active中的進程一旦用完了自己的時間片,就被轉(zhuǎn)移到expired中,并設(shè)置好新的初始時間片;而當actived為空時,則表示當前所有進程的時間片都消耗完了,此時,active和expired進行一次對調(diào),重新開始下一輪的時間片遞減過程。而runqueue就是調(diào)度程序操作的對象。進程在初始化并放入運行隊列后,在某個時刻,它應(yīng)該獲得對CPU的訪問。負責把CPU的控制權(quán)傳遞到不同的兩個函數(shù)是schedule()和scheduler_tick()。scheduler_tick()是一個由內(nèi)核周期性調(diào)用的系統(tǒng)定時器,它把進程標記為需重新調(diào)度。一般定時事件發(fā)生時,當前的進程就被保存起來,Linux內(nèi)核接管對CPU的控制,而當定時事件完成后,Linux內(nèi)核通常把控制權(quán)傳回被保存的進程。然而,當所保存的進程被標記成需重新調(diào)度時,并不一定選擇內(nèi)核接管控制前正在執(zhí)行的那個進程,而是內(nèi)核調(diào)用schedule()來選擇需要激活哪一個進程。圖2-3調(diào)度過程圖2-3說明隨著時間的推移,如何在不同的進程之間傳遞CPU。我們看到,進程A最先擁有CPU的控制權(quán)并正在執(zhí)行。系統(tǒng)定時scheduler_tick()執(zhí)行,從A獲取對CPU的控制權(quán),此時scheduler_tick()把A標記為需要重新調(diào)度。Linux內(nèi)核調(diào)用scheduler(),scheduler()選擇進程B,因此CPU的控制權(quán)被交給B。進程B執(zhí)行一會兒,然后自動放棄CPU。這通常發(fā)生在進程等待資源的時候。進程B調(diào)用scheduler(),scheduler()選擇進程C繼續(xù)執(zhí)行。進程C執(zhí)行,直到scheduler_tick()發(fā)生,scheduler_tick()不把進程C標記為需要調(diào)度。這導致了scheduler()不被調(diào)用,因此,進程C再次獲得CPU的控制權(quán)。通過調(diào)用scheduler(),進程C放棄CPU,scheduler()決定進程A應(yīng)該獲得CPU的控制權(quán),進程A再次開始執(zhí)行。我們首先分析scheduler(),Linux內(nèi)核利用它決定哪個進程接下來要執(zhí)行,然后,在分析scheduler_tick(),內(nèi)核利用它決定哪個進程必須讓出CPU。這兩個函數(shù)組合的結(jié)果說明了調(diào)度程序的控制流程[10]。函數(shù)schedule分析在include/Linux/sched.h中有調(diào)度策略定義如圖2-4:圖2-4Linux進程狀態(tài)定義策略進程的task_struct結(jié)構(gòu)中成員policy是進程的調(diào)度策略,它的值為上述三種策略之一,進程分為實時進程和普通進程,實時進程優(yōu)先于普通進程運行。rt_priority是實時進程的優(yōu)先級,它比普通進程的priority高。當系統(tǒng)中有一個實時進程運行時,則SCHED_NORMAL進程不能在任何CPU運行,只有root用戶能夠用系統(tǒng)調(diào)用sched_setscheduler來修改當前進程的優(yōu)先級。[10]函數(shù)schedule的功能是選擇一個合適的進程在CPU上運行,它的基本流程分為五個操作步驟:清理當前運行中的進程。選擇下一個投入運行的進程。設(shè)置新進程的運行環(huán)境執(zhí)行進程上下文切換。后期處理。進程調(diào)度有直接啟動調(diào)度和被動啟動調(diào)動兩種方式,在不同的方式下調(diào)度執(zhí)行的步驟是不一樣的。直接啟動調(diào)度

直接啟動調(diào)度發(fā)生在當前進程因等待資源而需要進入被阻塞狀態(tài)時,調(diào)度程序執(zhí)行的步驟如下:把當前進程(全局變量current指向task_struct變量)放到適當?shù)牡却犃欣铮话旬斍斑M程的state設(shè)為TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE調(diào)用schedule(),準備讓新的進程掌握CPU;檢查當前進程所需的資源是否可用,如果是,則把當前進程從等待隊列里刪除,否則會到步驟b被動調(diào)度

通過在當前進程的need_resched設(shè)為1來實現(xiàn)被動調(diào)度,每次調(diào)入一個用戶太進程之前,這個變量的值都會被檢查,來決定是否調(diào)用函數(shù)schedule()來實現(xiàn)調(diào)度。具體執(zhí)行方式為:當當前進程用完了它的CPU時間片,update_process_times()重新進行計算。當一個進程被喚醒,而且他的優(yōu)先級比當前進程高。Wake_up_process()調(diào)用reschedule_idle(),設(shè)置當前進程的need_resched,使被喚醒的進程盡快掌握CPU當sched_setscheduler()或sched_yield()系統(tǒng)調(diào)用被調(diào)用的進程函數(shù)scheduler_tick分析通過調(diào)用schedule()可使進程自動放棄CPU。在向要睡眠或等待信號發(fā)生的內(nèi)核代碼及設(shè)備驅(qū)動中。這個函數(shù)用得非常普遍。若其他進程想要連續(xù)的使用CPU,系統(tǒng)定時器必須告訴它們讓出CPU。Linux內(nèi)核定時地奪取CPU,然后執(zhí)行基于定時器的許多任務(wù)。其中,這些任務(wù)之一就是scheduler_tick(),它是內(nèi)核強迫一個進程放棄CPU的函數(shù)。首先scheduler_tick先收集CPU的統(tǒng)計,然后查看當前進程是否不再活躍。如果進程已經(jīng)過期,調(diào)度程序設(shè)置進程的重新調(diào)度標志,并跳轉(zhuǎn)到scheduler_tick()函數(shù)的結(jié)尾。如果得知當前進程正在運行,調(diào)度程序就先為剝奪CPU控制權(quán)而申請運行隊列鎖。先考慮最簡單的情況。如果當前進程是實時進程,由于實時進程總是擁有比其他任何進程都搞得優(yōu)先級,當該進程是FIFO進程并且正在運行,進程應(yīng)該繼續(xù)它的操作,因此,我們跳轉(zhuǎn)到函數(shù)的末尾并釋放運行隊列鎖。如果當前進程是時間片輪轉(zhuǎn)實時進程,我們就減小其時間片,然后調(diào)度另一個輪轉(zhuǎn)實時進程,當前進程通過task_timeslice()計算其新的時間按片,最后通過從運行隊列的活躍數(shù)組刪除進程并把其添加回活躍數(shù)組,進程被放到輪轉(zhuǎn)實時進程鏈表的末尾,最后釋放運行隊列鎖。通過了上面的嘗試,如果調(diào)度程序發(fā)現(xiàn)當前并非實時進程。它減小進程的時間片,如果時間片被耗盡。調(diào)度程序從活躍數(shù)組刪除進程并設(shè)置它的需要重新調(diào)度標志。重新計算進程的優(yōu)先級并重置它的時間片。最后一種情況,就是進程正在運行并且還有剩余時間片可運行。調(diào)度程序必須確保擁有大時間片的進程不會獨占CPU。如果進程是交互式的,擁有多余TIMESLICE_GRANULARITY的時間片,而且是活躍的,調(diào)度程序就將它從活躍隊列中刪除。然后,重新調(diào)度標志置位,重新計算它的優(yōu)先級后被放回運行隊列的活躍數(shù)組,這確保了擁有大時間片的某個優(yōu)先權(quán)的進程不會餓死同等優(yōu)先權(quán)的其它進程。2.2.2搶占搶占指一個進程到另一個進程的切換。前面介紹了schedule()和scheduler_tick()是如何決定接下來要切換哪一個進程的,但沒有提及Linux內(nèi)核是如何決定何時進行切換的。2.6內(nèi)核引入了內(nèi)核搶占,這意味著用戶空間的程序和內(nèi)核空間的程序能夠在各種時刻被切換。下面將從顯式和隱式分別對內(nèi)核與用戶搶占進行描述。[11]顯式內(nèi)核搶占這種情況發(fā)生內(nèi)核調(diào)用schedule()時的內(nèi)核空間,內(nèi)核代碼可以用兩種方式調(diào)用schedule():直接調(diào)用schedule()或者通過阻塞調(diào)用。當顯式地搶占內(nèi)核時,例如,在wait_queue等待隊列中設(shè)備驅(qū)動程序在等待時,控制權(quán)被簡單地傳遞到調(diào)度程序,從而新的進程被選中執(zhí)行。隱式用戶搶占當內(nèi)核處理完內(nèi)核空間的進程并準備把控制權(quán)傳遞到用戶空間的進程時,它首先查看應(yīng)該把控制權(quán)傳遞到哪一個用戶空間的進程。而這個進程也許不是傳遞其控制權(quán)到內(nèi)核的那個用戶空間進程。例如,如果進程A調(diào)用了系統(tǒng)調(diào)用,系統(tǒng)調(diào)用完成之后,內(nèi)核可能把系統(tǒng)的控制權(quán)傳遞給進程B。出現(xiàn)這種情況的主要原因是系統(tǒng)中的每一個進程有一個“必須重新調(diào)度”標志,在進程應(yīng)該被重新調(diào)度的任何時候設(shè)置它。當內(nèi)核正在向用戶空間返回時,如同schedule()和scheduler_tick()中描述的那樣,它選擇一個進程,并把控制權(quán)傳遞給該進程。盡管scheduler_tick()能夠把進程標記為需要重新調(diào)度,但是只有schedule()能夠?qū)@個標記進行操作。schedule()反復選擇一個新進程來執(zhí)行,直到新選擇的進程不需要被重新調(diào)度。schedule()完成后,新進程擁有對CPU的控制權(quán)。因此,當進程正在運行時,系統(tǒng)定時器引起一個觸發(fā)scheduler_tick()的中斷。scheduler_tick()能夠標記哪個任務(wù)需要重新調(diào)度,并能把它移動至到期數(shù)組。在內(nèi)核操作完成之后,scheduler_tick()的后面可能緊接著其他中斷,內(nèi)核將繼續(xù)擁有對處理器的控制權(quán)。調(diào)用schedule()選擇下一個要運行的進程。這樣看來,scheduler_tick()標記進程并重排隊列,而schedule()選擇下一個進程并傳遞CPU的控制權(quán)。隱式內(nèi)核搶占Linux2.6中新增了隱式內(nèi)核搶占的實現(xiàn)。當一個內(nèi)核進程擁有對CPU的控制權(quán)時,僅當其當前沒有持有任何鎖時,這個內(nèi)核進程才能被另一個內(nèi)核進程所搶占。每個進程有一個域preempt_count,它標記進程是否可以搶占。每當進程獲得一個鎖時,則該計數(shù)增加,每當進程釋放一個鎖時減少。當一個進程仍然有一個正的preempt_count值,就把CPU控制權(quán)返回給當前進程。如果當前進程沒有鎖,因為preempt_count是0且中斷請求是激活的,這樣該進程就可能會被搶占。[10]2.2.3調(diào)度器的實時性能Linux2.6對實時性能的改進

Linux2.6內(nèi)核調(diào)度系統(tǒng)對調(diào)度的實時性作了改進,它體現(xiàn)了內(nèi)核搶占和O(1)調(diào)度,這加快了實時進程的響應(yīng)。但Linux2.6調(diào)度系統(tǒng)僅提供了對CPU資源的剝奪能力,因此它的實時性并沒有得到根本改觀。所以Linux2.6只能作為軟實時操作系統(tǒng)。實時進程的優(yōu)先級

在Linux2.4中,實時進程的優(yōu)先級通過rt_priority值表示,與非實時進程不同。Linux2.6在靜態(tài)優(yōu)先級之外引入了動態(tài)優(yōu)先級屬性,并用它同時表示實時進程和非實時進程的優(yōu)先級。進程的靜態(tài)優(yōu)先級是計算進程初始時間片的基礎(chǔ),動態(tài)優(yōu)先級則決定了進程的實際調(diào)度優(yōu)先順序。因為實時進程的動態(tài)優(yōu)先級在setscheduler()中設(shè)置,并不隨進程的運行而改變。所以實時進程的靜態(tài)優(yōu)先級僅用于計算時間片,而動態(tài)優(yōu)先級則相當于靜態(tài)。實時調(diào)度

linux2.4種的SCHED_RR和SCHED_FIFO兩種實時調(diào)度策略在Linux2.6中未做改變,兩類實時進程都回保持在active就緒隊列中運行,只是因為Linux2.6內(nèi)核是可搶占的,實時進程(特別是核心級的實時進程)更能迅速地對環(huán)境的改變(比如出現(xiàn)更高優(yōu)先級進程)作出反應(yīng)。[11]3構(gòu)造嵌入式Linux系統(tǒng)Linux作為一種通用操作系統(tǒng),其最初的設(shè)計是用于桌面系統(tǒng)或者小型服務(wù)器。在將Linux用于嵌入式系統(tǒng)中時,由于受到嵌入式軟/硬件環(huán)境的制約,需要對Linux內(nèi)核做一些改進,使它能更好地為嵌入式系統(tǒng)服務(wù)。在這些改進中,進程管理是相當重要的一環(huán)。從芯片到外圍電路再到人機接口,嵌入式系統(tǒng)的這些硬件設(shè)備與普通PC是截然不同的。由于降低成本和功耗,嵌入式系統(tǒng)CPU可能不帶MMU(存儲器管理單元),使用的存儲設(shè)備ROM、Flash及RAM的容量較小,這些因素決定了須改變Linux進程管理,以適應(yīng)存儲系統(tǒng)方面的變化。[11]3.1uClinux結(jié)局方案Lineo公司的uClinux就是專門針對無MMU處理器的嵌入式設(shè)備的Linux變種。由于uClinux沒有MMU,在實現(xiàn)多進程時(fork調(diào)用產(chǎn)生子進程)須實現(xiàn)數(shù)據(jù)保護。由于uClinux的多進程管理是通過vfork來實現(xiàn)的,因此fork等于vfork。這意味著uClinux系統(tǒng)fork調(diào)用完成后,或者子進程代替父進程執(zhí)行(此時父進程已經(jīng)sleep),直到子進程調(diào)用exit推出;或者調(diào)用exec執(zhí)行一個新進程,此時將產(chǎn)生執(zhí)行文件加載,即使這個進程只是父進程的拷貝,這個過程也是不可避免的。當子進程執(zhí)行exit或exec后,子進程使用wakeup把父進程喚醒,使父進程繼續(xù)往下執(zhí)行。uClinux的這種多進程實現(xiàn)機制與它的內(nèi)存管理緊密相關(guān)。uClinux針對沒有MMU的處理器開發(fā),所以須使用一種flat方式的內(nèi)存管理模式。在啟動新的應(yīng)用程序時,系統(tǒng)必須為應(yīng)用程序分配存儲空間。uClinux本身并沒于關(guān)注實時問題,它并不時為了Linux的實時性而提出的。因此若將uClinux用于實時性要求較高的場合,則需要對其內(nèi)核做必要的改進。嵌入式Linux的另一個版本RT-Linux關(guān)注實時問題。RT-linux把普通Linux的內(nèi)核當成一個任務(wù)運行,同時還管理了實時進程,而非實時進程則交給普通Linux內(nèi)核處理。這種方法已廣泛應(yīng)用于增強操作系統(tǒng)得實時性,包括一些商業(yè)版Unix系統(tǒng)和WindowNT等等。這種方法的優(yōu)點是:實現(xiàn)簡單,且實時性能容易檢驗;非實時系統(tǒng)運行于標準Linux系統(tǒng),與其他Linux商用版本之間保持了很好的兼容性;可支持硬實時時鐘的應(yīng)用。uClinux可使用RT-linux的patch,從而增強uClinux的實時性,使得uClinux可應(yīng)用于工業(yè)標準、進程控制等一些實時要求較高的場合。在普通PC中,外部存儲介質(zhì)一般都是使用IDE硬盤等傳統(tǒng)的外存設(shè)備;而在嵌入式系統(tǒng)中,各種特殊應(yīng)用目的對存儲設(shè)備提出了各種各樣的要求,所以在不同的場合,需要因地制宜地選擇存儲設(shè)備。目前,F(xiàn)lash存儲設(shè)備由于其安全性高,存儲密度大,體積小,價格相對低廉,成為嵌入式領(lǐng)域中最受歡迎的一類存儲器。在嵌入式系統(tǒng)中使用Flash存儲器,可只進行只讀訪問,再將內(nèi)核與文件系統(tǒng)寫到Flash上之后,不需要再對Flash進行寫操作。在這種情況下,只需要將Flash作為普通ROM來使用,或輔以romfs和cramfs等,即可滿足要求。在運行時,系統(tǒng)會把需要操作的文件和目錄提取到內(nèi)存中進行操作。由于不能再Flash上寫數(shù)據(jù),所以運行時的欣喜都不可保存于Flash存儲設(shè)備中。所以對Flash存儲設(shè)備的管理非常簡單,與普通的ROM沒有什么區(qū)別。uClinux系統(tǒng)采用romfs(romfilesystem)文件系統(tǒng)。Romfs是一種只讀文件系統(tǒng)。起初,設(shè)計它的目的是在啟動盤等場合下,提供一個比普通文件系統(tǒng)(如功能強大的ext2)更加節(jié)省空間的文件系統(tǒng)??臻g的節(jié)省來自于兩個方面:首先,內(nèi)核支持romfs文件系統(tǒng)比支持ext2文件系統(tǒng)需要更少的代碼;其次,romfs文件系統(tǒng)相對簡單,在建立文件系統(tǒng)超級塊(Superglock)時,需要更少的存儲空間。romfs文件系統(tǒng)不支持動態(tài)擦寫保存,對于系統(tǒng)需要動態(tài)保存的數(shù)據(jù),可采用虛擬RAM盤的方法處理(RAM盤將采用ext2文件系統(tǒng))。3.2構(gòu)造潛入式Linux系統(tǒng)3.2.1構(gòu)建嵌入式Linux系統(tǒng)的幾個關(guān)鍵問題一個小型的嵌入式Linux系統(tǒng)需要具備3個基本元素:引導工具、Linux微內(nèi)核(由內(nèi)存管理、進程管理和實物處理構(gòu)成)及初始化進程。若想讓它做些什么且繼續(xù)保持小型化,還須具備:硬件驅(qū)動程序,提供所需要功能的一個或多個應(yīng)用程序。若需要增加功能,或許需要:一個文件系統(tǒng)(也許在ROM或RAM中)、TCP/IP網(wǎng)絡(luò)協(xié)議棧及一個磁盤,用于存放半易失數(shù)據(jù)和提供交換能力。由此可見,構(gòu)造一個嵌入式Linux系統(tǒng),關(guān)鍵是解決以下幾個問題。如何引導

當一個微處理器第一次啟動時,它開始在預(yù)先設(shè)置的地址上執(zhí)行指令。通常在那里有一些只讀內(nèi)存,包括初始化或引導代碼。在PC上,這就是BIOS。BIOS首先執(zhí)行一些低水平的CPU初始化其他硬件的配置,接著辨認哪個磁盤里有操作系統(tǒng),把操作系統(tǒng)復制到RAM,并且轉(zhuǎn)向它。在PC上運行的Linux就是依靠PC的BIOS來提供相關(guān)配置和加載OS功能的。

在一個嵌入式系統(tǒng)中,處于經(jīng)濟性、價格方面的考慮,通常沒有BIOS。這就需要開發(fā)者自行提供完成這些工作所需要的程序,這就是所需要的開機啟動代碼。幸運的是,潛入式系統(tǒng)的啟動代碼不需要像PCBIOS引導程序那樣靈活,因為它通常只須處理一些硬件的配置。因此啟動代碼只是一個指令清單,將固定的數(shù)字賽到硬件的寄存器中去。這個代碼很簡單,也很枯燥,然而卻非常關(guān)鍵,因此這些數(shù)值要與硬件相符,而且要按照指定的順序進行。嵌入式系統(tǒng)中啟動代碼通常放在Flash或EPROM芯片上。具體如何實現(xiàn),要根據(jù)目標硬件和工具來定。一種常用的方法是,把Flash或EPROM芯片插入EPROM或Flash燒制器,把啟動代碼燒入芯片,然后將芯片插入目標板插座,這種方法要求目標上配有插座。另一種方法是通過JTAG界面,一些芯片有JTAG界面,可用來對芯片進行進行編程,這樣芯片就可以被焊在主板上。是否需要虛擬內(nèi)存

標準Linux采用虛擬存儲器技術(shù)來管理內(nèi)存,其優(yōu)點是提供了比計算機系統(tǒng)實際物理內(nèi)存大得多的內(nèi)存空間。這樣編程人員在編程時,勿需考慮計算機中物理內(nèi)存的實際容量。當然它也存在缺點,虛擬內(nèi)存管理需要通過內(nèi)存管理單元MMU將虛擬地址轉(zhuǎn)換為物理地址。其中的地址轉(zhuǎn)換表和其他一些數(shù)據(jù)結(jié)構(gòu)占據(jù)了內(nèi)存空間,這樣留給編程人員的內(nèi)存空間就減少了;同時地址轉(zhuǎn)換增加了每一條指令的執(zhí)行時間。

在嵌入式系統(tǒng)中,虛擬內(nèi)存管理并無用武之地;同時在嵌入式實時系統(tǒng)中,它可能會帶來無法控制的時間問題。但明智的做法并不是消除內(nèi)核中的虛擬內(nèi)存代碼,基于兩點原因:一是消除它很費事;二是它支持共享代碼,多個進程可以共享某一軟件的同一拷貝。因此,可保留這段代碼,同時只需將交換空間的大小簡單地設(shè)置為零,就可以關(guān)掉虛擬內(nèi)存的調(diào)用功能。此后,如果用戶寫的程序比實際內(nèi)存大,系統(tǒng)就會當作用盡了交換空間來處理。這個程序?qū)⒉粫\行,或者malloc將會失靈。文件系統(tǒng)選擇

許多嵌入式系統(tǒng)沒有磁盤或者文件系統(tǒng),Linux不需要它們也能運行。這種情況下,應(yīng)用程序任務(wù)可與內(nèi)核一起編寫,并且在引導時作為一個映像加載。對于簡單的系統(tǒng)來說,這足夠了,但缺乏靈活性。實際上,許多商業(yè)性嵌入式操作系統(tǒng)提供文件系統(tǒng)作為選項。Linux提供MS-DOS-Compatible以及其他功能更強大的文家年系統(tǒng)。

文件系統(tǒng)可放在傳統(tǒng)的磁盤驅(qū)動器、FlashMemory或其他類似的介質(zhì)上。如果用于暫時保存文件,一個小RAM盤就足夠了,F(xiàn)lashMemory通常是這樣保存文件系統(tǒng)的:FlashMemory杯分割成塊,其中有一塊是黨CPU啟動運行時的引導塊,里面存放Linux引導代碼,剩余的Flash可用作文件系統(tǒng)。Linux內(nèi)核有兩種加載方式:一是把內(nèi)核的可執(zhí)行映像存儲到Flash的一個獨立部分,系統(tǒng)啟動時,從Flash的某個地址開始逐句執(zhí)行;另一種方式是把內(nèi)核的壓縮文件放在Flash上,系統(tǒng)啟動時通過引導代碼把內(nèi)核壓縮文件從Flash復制到RAM里,解壓執(zhí)行。因為RAM的存取速度高于Flash,所以后一種方式的運行速度更高一些,標準Linux就是采用這種方式。消除潛入式Linux系統(tǒng)對磁盤的依賴

標準Linux內(nèi)核通常主流在內(nèi)存中,每一個應(yīng)用程序都是從磁盤運行到內(nèi)存上執(zhí)行。當程序結(jié)束后,它所占的內(nèi)存被釋放,程序就被卸載了。在一個嵌入式系統(tǒng)中,可能沒有磁盤。有兩條途徑可以消除對磁盤的依賴,這要看系統(tǒng)的復雜性和硬件的設(shè)計如何:

在一個簡單的系統(tǒng)中,當系統(tǒng)啟動后,內(nèi)核和所有的應(yīng)用程序都在內(nèi)存里。這是大多數(shù)傳統(tǒng)潛入式系統(tǒng)的工作模式,它同樣也被Linux支持。

有了Linux,就有了第二種可能性,因為Linux有能力加載和卸載程序,一個嵌入式系統(tǒng)可利用它來節(jié)省內(nèi)存。在一個典型的具有FlashMemory的嵌入式系統(tǒng)中,F(xiàn)lashMemory上裝有文件系統(tǒng),所有的程序都以文件的形式存儲在Flash文件中,需要時裝入內(nèi)存。這種動態(tài)的、根據(jù)需要加載的能力是支持其他一系列功能的重要特征。

它使初始化代碼在系統(tǒng)引導后被釋放。Linux有很多內(nèi)核外運行的公用程序,這些程序通常在初始化時運行一次,以后不再運行;而且,這些公用程序可以它們共有的方式一個接一個地按順序運行。這樣,相同的內(nèi)存空間可被反復使用,以“召入”每一個程序,達到節(jié)省內(nèi)存空間的目的。

如果Linux可加載模塊的功能包括在內(nèi)核里,那么驅(qū)動程序和應(yīng)用程序就都可以被加載。它可檢查硬件環(huán)境,并且為硬件裝上相應(yīng)的軟件,這就消除了用一個程序占用很多FlashMemory來處理多種硬件所引起的復雜性。

軟件的升級更模塊化??稍谙到y(tǒng)運行時,在Flash上升級應(yīng)用程序和可加載的驅(qū)動程序。配置信息和運行時間參數(shù)可作為數(shù)據(jù)文件存儲在Flash上。3.2.1構(gòu)建嵌入式Linux系統(tǒng)的關(guān)鍵步驟嵌入式應(yīng)用開發(fā)環(huán)境一般是由目標系統(tǒng)(硬件開發(fā)板)和宿主PC機構(gòu)成。硬件開發(fā)板用于操作系統(tǒng)和目標系統(tǒng)應(yīng)用軟件的運行;而操作系統(tǒng)內(nèi)核的編程、應(yīng)用程序的開發(fā)和調(diào)試則須借助宿主PC機完成。雙方一般通過串口建立連接通信。建立交叉開發(fā)環(huán)境

在軟件開發(fā)環(huán)境建立方面,由于uClinux及相關(guān)工具集都是開放源碼項目,所以大多數(shù)軟件都可以從網(wǎng)站上下載獲得。首先要在宿主機上安裝標準Linux發(fā)行版,比如RedHatLinux,接下來就是建立交叉開發(fā)環(huán)境。安裝交叉編譯工具

uClinux編譯工具中的交叉編譯器可對源代碼包括內(nèi)核進行編譯,以適應(yīng)不同的嵌入式應(yīng)用場合。編譯工具包中除了交叉編譯器,還有鏈接器、匯編器以及一些為了方便開發(fā)的二進制處理工具,包括生成靜態(tài)庫工具、二進制碼察看工具及二進制格式轉(zhuǎn)換工具。這些都要安裝在宿主機上。安裝uClinux內(nèi)核

利用已安裝的交叉編譯器編譯生成與運行目標機上的uClinux內(nèi)核。與標準Linux相同的是,uClinux內(nèi)核可以以配置的方式選擇需要安裝的模塊,而增加系統(tǒng)的靈活性。安裝應(yīng)用程序

用交叉編譯器編譯uC-libc和uC-libm源碼,聲稱libc.a應(yīng)用程序庫和libm.a數(shù)學庫。安裝其他工具

用GCC編譯elf2flt源碼,聲稱格式轉(zhuǎn)換工具elf2flt。用GCC編譯genromfs源碼,得到生成romfs的工具genromfs。經(jīng)過以上的準備工作之后,下面要針對特定應(yīng)用所需要的設(shè)備編寫或改造設(shè)備驅(qū)動程序。有如果用戶對系統(tǒng)實時性,特別是對硬實時有特殊要求,uClinux可以加入RT-linux的實時模塊。3.3uClinux在ARMulator的移植盡管uClinux很小,但它支持Linux2.6內(nèi)核約定的全部的特性,包括內(nèi)核優(yōu)先級特性以及許多的文件系統(tǒng),設(shè)備驅(qū)動。為Linux約定設(shè)備驅(qū)動端口是容易實現(xiàn)的。幾乎所有的代碼不需要改變就可以編譯,除了從虛擬地址到物理的內(nèi)存鏡像外。

下面將介紹如何將uClinux2.6.5移植到基于GDB的ARMulator上。從uC站點上下載uClinux發(fā)布包

,本文以uClinux-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的源文件。從站點上更新的ARM-ELF工具鏈來編譯內(nèi)核,本文以arm-elf-tools-20040427.sh為例。構(gòu)造虛擬硬件環(huán)境ARMulator(ARM仿真)安裝工具鏈。以root身份登陸宿主機下的Llinux系統(tǒng),然后在終端中進入存放工具鏈的所在目錄,然后輸入/bin/sh

arm-elf-tools-20040427.sh解壓uClinux發(fā)布包

并將linux2.6.5源文件和補丁解壓到相同目錄下。修改vendors/GDB/ARMulator目錄下面的ARMulator默認的配置文件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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論