嵌入式操作系統(tǒng)_第1頁
嵌入式操作系統(tǒng)_第2頁
嵌入式操作系統(tǒng)_第3頁
嵌入式操作系統(tǒng)_第4頁
嵌入式操作系統(tǒng)_第5頁
已閱讀5頁,還剩56頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

嵌入式操作系統(tǒng)第一頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)22.1Linux及其應用Linux操作系統(tǒng)是UNIX操作系統(tǒng)的一種克隆系統(tǒng)。它誕生于1991年的10月5日(這是第一次正式向外公布的時間)。此后借助于因特網,經過全世界各地計算機愛好者的共同努力,現(xiàn)已成為當今世界上使用最多的一種UNIX類操作系統(tǒng),并且使用人數(shù)還在迅猛增長。2.1.1Linux與UNIX和GNU2.1.2Linux的特點2.1.3Linux的發(fā)展及應用第二頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)3Linux與UNIX和GNUUNIX操作系統(tǒng)是美國貝爾實驗室的Ken.Thompson和DennisRitchie于1969年夏在DECPDP-7小型計算機上開發(fā)的一個分時操作系統(tǒng)。KenThompson在1969年夏天利用一個月的時間開發(fā)了UNIX操作系統(tǒng)的原型。后經DennisRitchie于1972年用移植性很強的C語言進行了改寫,使得UNIX系統(tǒng)在大專院校得到了推廣。MINIX系統(tǒng)是由AndrewS.Tanenbaum(AST)于1987年開發(fā)的,主要用于學生學習操作系統(tǒng)原理。AST工作在荷蘭Amsterdam的Vrije大學,并從事數(shù)學與計算機科學系統(tǒng)研究,是ACM和IEEE的資深會員(全世界也只有很少人是兩會的資深會員)。GNU計劃和自由軟件基金會FSF(theFreeSoftwareFoundation)是由RichardM.Stallman于1984年一手創(chuàng)辦的,旨在開發(fā)一個類似UNIX,并且是自由軟件的完整操作系統(tǒng):GNU系統(tǒng)(GNU是“GNU’sNotUNIX”的遞歸縮寫,它的發(fā)音為“gun-NEW”)。各種使用Linux作為核心的GNU操作系統(tǒng)正在被廣泛地使用。雖然這些系統(tǒng)通常被稱為“Linux”,但是Stallman認為,以嚴格意義上講,它們應該被稱為GNU/Linux系統(tǒng)。到20世紀90年代初,GNU項目已經開發(fā)出許多高質量的免費軟件,其中包括有名的emacs編輯系統(tǒng)、bashshell程序、gcc系列編譯程序、gdb調試程序,等等。這些軟件為Linux操作系統(tǒng)的開發(fā)創(chuàng)造了一個合適的環(huán)境,這也是Linux能夠誕生的基礎之一,以至于目前許多人都將Linux操作系統(tǒng)稱為“GNU/Linux”操作系統(tǒng)。第三頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)4POSIX(PortableOperatingSystemInterfaceforComputingSystems)是由IEEE和ISO/IEC開發(fā)的一組標準。該標準是基于現(xiàn)有UNIX的實踐經驗,描述了操作系統(tǒng)的調用服務接口。用于保證編制的應用程序可以在源代碼一級上、在多種操作系統(tǒng)上移植和運行。它是在1980年一個UNIX用戶組(usr/group)的早期工作基礎上完成的。20世紀90年代初,POSIX標準的制定處于最后投票敲定的時候,此時也正是Linux剛剛起步的時候,這個UNIX標準為Linux提供了極為重要的信息,使得Linux能夠在標準的指導下進行開發(fā),并能夠與絕大多數(shù)UNIX操作系統(tǒng)兼容。通過上述說明,我們可以對上述Linux的5大支柱歸納如下:

UNIX操作系統(tǒng)——Linux就是UNIX的一種克隆系統(tǒng)。UNIX的重要性就不用多說了。

MINIX操作系統(tǒng)——MINIX操作系統(tǒng)也是UNIX的一種克隆系統(tǒng),它于1987年由著名計算機教授AndrewS.Tanenbaum開發(fā)完成。由于MINIX系統(tǒng)的出現(xiàn)并且提供源代碼(只能免費用于大學內),在全世界的大學中刮起了學習UNIX系統(tǒng)旋風。Linux剛開始就是參照MINIX系統(tǒng)于1991年才開始開發(fā)。

GNU計劃——開發(fā)Linux操作系統(tǒng),以及Linux上所用大多數(shù)軟件基本上都出自GNU計劃。Linux只是操作系統(tǒng)的一個內核,沒有GNU軟件環(huán)境(如bashshell),則Linux將寸步難行。

POSIX標準——該標準在推動Linux操作系統(tǒng)以后朝著正規(guī)路上發(fā)展起著重要的作用,是Linux前進的燈塔。

Internet——如果沒有Internet網,沒有遍布全世界的無數(shù)計算機黑客的無私奉獻,那么Linux最多只能發(fā)展到0.13(0.95)版的水平第四頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)5Linux的特點1.開放性是指系統(tǒng)遵循世界標準規(guī)范,特別是遵循開放系統(tǒng)互聯(lián)(OSI)國際標準。凡遵循國際標準所開發(fā)的硬件和軟件,都能彼此兼容,可方便地實現(xiàn)互聯(lián)。Linux采用GPL授權,除了把源代碼公開以外,任何人都可以自由使用、修改、散布;而Linux核心本身采用模塊化設計,讓人很容易增減功能,由于Linux具有這樣高的可伸縮性,所以可以調出最適合我們硬件平臺的核心出來。2.多用戶是指系統(tǒng)資源可以被不同用戶各自擁有并使用,即每個用戶對自己的資源有特定的權限,互不影響。Linux和UNIX都具有多用戶的特性。3.多任務是現(xiàn)代計算機最主要的一個特點。它是指計算機同時執(zhí)行多個程序,而且各個程序的運行互相獨立。Linux系統(tǒng)調度每一個進程平等地訪問微處理器。由于CPU的處理速度非???,其結果是,啟動的應用程序看起來好像在并行運行。4.穩(wěn)定性強,Linux不屬于任何一家公司,但它卻擁有全世界愿意投入自由軟件的開發(fā)人員。在全球各處都有無數(shù)的人參與Linux核心的改進、調試與測試,也正因此造就了穩(wěn)定度高的Linux。所以,Linux雖不是商業(yè)的產物,但它的質量卻不遜于商業(yè)產品。5.設備獨立性,是指操作系統(tǒng)把所有外部設備統(tǒng)一當做文件來看待,只要安裝它們的驅動程序,任何用戶都可以像使用文件一樣,操縱、使用這些設備,而不必知道它們的具體存在形式。另外,由于用戶可以免費得到Linux的內核源代碼,因此,用戶可以修改內核源代碼,以便適應新增加的外部設備。第五頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)66.提供了豐富的網絡功能完善的內置網絡是Linux的一大特點。Linux在通信和網絡功能方面優(yōu)于其他操作系統(tǒng)。Linux為用戶提供了完善的、強大的網絡功能,包括支持Internet、文件傳輸和遠程訪問。7.可靠的系統(tǒng)安全在Linux操作系統(tǒng)中采取了許多安全技術措施,包括對讀、寫進行權限控制、帶保護的子系統(tǒng)、審計跟蹤、核心授權等,這些措施為網絡多用戶環(huán)境中的用戶提供了必要的安全保障。8.良好的可移植性可移植性是指將操作系統(tǒng)從一個平臺轉移到另一個平臺,并使它仍然能按其自身的方式運行的能力。Linux一開始是基于Intel386機器設計的,但是隨著網絡的散布,加上有許多工程師致力于各式平臺的移植,使得Linux可以在x86、MIPS、ARM/StrongARM、PowerPC、Motorola68k、HitachiSH3/SH4、Transmeta等平臺上運行。這些平臺幾乎覆蓋了所有嵌入式系統(tǒng)的CPU種類,這樣,在硬件平臺設計時,使得可以考慮的CPU種類增加了不少。9.應用軟件多自由軟件世界里有個很大的特點就是軟件多,授權幾乎都是采用GPL方式,大家都可以自由參考與使用,但是因為這些軟件多半是由設計者利用空余時間開發(fā)的,不以贏利為目的,所以并不能擔保這些軟件完全沒有問題。盡管如此,仍有許多優(yōu)秀軟件出現(xiàn),例如,大家熟知的KDE與GNOME便是很好的證明。第六頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)7Linux的發(fā)展及應用1991年10月5日,LinusTorvalds在新聞組comp.os.minix發(fā)布了大約有1萬行代碼的Linuxv0.01版本。1992年,大約有1000人在使用Linux,基本上都屬于真正意義上的黑客。1993年,大約有100余名程序員參與Linux內核代碼編寫/修改工作,其中核心組由5人組成,此時Linux0.99的代碼大約有十萬行,用戶大約有10萬個左右。1994年3月,Linux1.0發(fā)布,代碼量為17萬行,正式采用GPL協(xié)議。Linux的代碼中充實了對不同硬件系統(tǒng)的支持,大大提高了跨平臺移植性。1995年,Linux可在Intel、Digital,以及SunSPARC處理器上運行了,用戶量也超過了50萬,相關介紹Linux的LinuxJournal雜志的發(fā)行也超過10萬冊。1996年6月,Linux2.0內核發(fā)布,此內核大約有40萬行代碼,并可以支持多個處理器。此時的Linux已經進入了實用階段,全球大約有350萬人使用。1997年夏,好萊塢影片《泰坦尼克號》在制作特效中使用的160臺Alpha圖形工作站中,有105臺采用了Linux操作系統(tǒng)。1998年是Linux迅猛發(fā)展的一年。RedHat5.0獲得了InfoWorld的操作系統(tǒng)獎項。4月,Mozilla代碼發(fā)布,成為Linux圖形界面上的王牌瀏覽器。王牌搜索引擎“Google”現(xiàn)身,采用的也是Linux服務器。Mysql數(shù)據(jù)庫充分得到發(fā)展。12月,IBM發(fā)布了適用于Linux的文件系統(tǒng)AFS3.5,以及JikesJava編輯器和SecureMailer及DB2測試版,IBM的此番行為,可以看做是與Linux的第一次親密接觸。迫于Windows和Linux的壓力,Sun逐漸開放了Java協(xié)議,并且在UltraSparc上支持Linux操作系統(tǒng)。由此可見,1998年可以說是Linux與商業(yè)接觸的一年。第七頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)81999年,IBM宣布與Redhat公司建立伙伴關系,以確保Redhat在IBM機器上正確運行。3月,第一屆LinuxWorld大會的召開,象征Linux時代的來臨。IBM、Compaq和Novell宣布投資Redhat公司,以前一直對Linux持否定態(tài)度的Oracle公司也宣布投資。5月,SGI公司宣布向Linux移植其先進的XFS文件系統(tǒng)。7月,IBM啟動對Linux的支持服務,并發(fā)布了LinuxDB2。2000年初始,Sun公司在Linux的壓力下宣布Solaris8降低售價。事實上,Linux對Sun造成的沖擊遠比對Windows來得更大。2月,RedHat發(fā)布了嵌入式Linux的開發(fā)環(huán)境,Linux在嵌入式行業(yè)的潛力逐漸被發(fā)掘出來。2001年Oracle宣布在OTN上的所有會員都可免費索取Oracle9i的Linux版本。IBM則決定投入10億美元擴大Linux系統(tǒng)的應用。到了5月,微軟公開反對“GPL”,此舉引起了一場大規(guī)模的論戰(zhàn)。8月,紅色代碼爆發(fā),引得許多站點紛紛從Windows操作系統(tǒng)轉向Linux操作系統(tǒng)。12月,RedHat為IBMs/390大型計算機提供了Linux解決方案。2002年是Linux企業(yè)化的一年。2月,微軟公司迫于各州政府的壓力,宣布擴大公開代碼行動,這是Linux開源帶來的深刻影響的結果。3月,內核開發(fā)者宣布新的Linux系統(tǒng)支持64位的計算機。2003年1月,NEC宣布將在其手機中使用Linux操作系統(tǒng),代表著Linux成功進軍手機領域。2004年6月的統(tǒng)計報告顯示在世界500強超級計算機系統(tǒng)中,使用Linux操作系統(tǒng)的已經占到了280席,搶占了原本屬于各種UNIX的份額。9月HP開始網羅Linux內核代碼人員,以影響新版本的內核朝對HP有利的方式發(fā)展,而IBM則準備推出OpenPower服務器,僅運行Linux系統(tǒng)。第八頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)9Linux的應用和優(yōu)勢(以銀行為例)銀行業(yè)是中國各行業(yè)中開展信息化建設最早的行業(yè)之一,其信息化建設投入力度大,信息化水平高,在各行業(yè)的IT應用和系統(tǒng)建設中走在前列。(1)銀行業(yè)的數(shù)據(jù)量大且集中決定了其對主機、存儲設備、網絡設備等硬件設備需求很大;同時對存儲管理、數(shù)據(jù)倉庫、網絡管理、網絡安全、CRM等方面的軟件需求也不小。正由于銀行業(yè)的數(shù)據(jù)量大且集中,因此金融安全問題也越發(fā)突出。Linux的高可靠性和安全性是它在這一行業(yè)中應用的有力保障。(2)對銀行業(yè)而言,成本因素在整體經濟環(huán)境欠佳的今天顯得尤其重要。選擇Linux的動力很大程度上來自于各個企業(yè)公司預算的減少。(3)Linux系統(tǒng)所具有的優(yōu)良集群特性也是吸引更多客戶的原因。Linux集群系統(tǒng)能夠讓客戶相對落后的PⅡ或PⅢ計算機變成可以處理復雜任務的超級計算機系統(tǒng)。這對客戶來說是非常有吸引力的。(4)北京市商業(yè)銀行綜合業(yè)務系統(tǒng)建設采用了基于IBMServeri系列服務器的Linux解決方案。該解決方案從整體上減少了總擁有成本,并且減少了系統(tǒng)管理的復雜性,實現(xiàn)了對人員、財政及信息技術的有效管理,同時還提高了服務器管理能力。(5)再以印度工業(yè)開發(fā)銀行(IDBI)為例。他們自1995年開始使用Linux系統(tǒng)從事關鍵的電話銀行、資產追蹤及人力資源管理等業(yè)務,IDBI因此節(jié)省的IT預算達到70%。(6)如今有越來越多的商業(yè)公司采用Linux作為操作系統(tǒng),例如,科學工作者使用Linux來進行分布式計算,ISP使用Linux配置Intranet服務器、電話撥號服務器等網絡服務器,CERN(西歐核子中心)采用Linux做物理數(shù)據(jù)處理。第九頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)102.2Linux內核由于的源代碼是完全公開的,任何人只要遵循GPL,就可以對內核加以修改并發(fā)布給他人使用。因此,在廣大編程人員的支持下,Linux的內核版本不斷更新,新的內核修改了舊內核的缺陷,并增加了許多新的特性。用戶如果想在自己的系統(tǒng)中使用這些新的特性,或想根據(jù)自己的系統(tǒng)量身定制更高效、更穩(wěn)定可靠的內核,只需要重新編譯內核。當內核的編譯工作完成之后,會生成一個可執(zhí)行的二進制文件,該二進制文件放入嵌入式系統(tǒng)的ROM中,可以完成系統(tǒng)的上電、復位自動運行。2.2.1Linux的內核特征2.2.2進程管理2.2.3內存管理2.2.4文件系統(tǒng)管理2.2.5設備管理2.2.6進程間通信機制第十頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)11Linux的內核特征內核是操作系統(tǒng)的內部核心程序,它向外部提供了對計算機設備的核心管理調用。操作系統(tǒng)的代碼分為以下兩部分,內核所在的地址空間稱為內核空間,外部管理程序與用戶進程所占據(jù)的地址空間稱為外部空間(用戶空間)。通常,一個程序會跨越兩個空間。當執(zhí)行到內核空間的一段代碼時,稱程序處于核心態(tài);而當程序執(zhí)行到外部空間代碼時,稱程序處于用戶態(tài)。單一內核(MonolithicKernel)曾經是操作系統(tǒng)的主流,它是指操作系統(tǒng)中所有的系統(tǒng)相關功能都被封裝在內核中。它們與外部程序處在不同的內存地址空間中,并通過各種方式防止外部程序直接訪問內核中的數(shù)據(jù)結構。程序只有通過一套稱作系統(tǒng)調用(SystemCall)的界面訪問內核結構。近些年來,微內核(MicroKernel)結構逐漸流行起來,成為操作系統(tǒng)的主要潮流。在微內核結構中,操作系統(tǒng)的內核只需要提供最基本、最核心的一部分操作(例如,創(chuàng)建和刪除任務、內存管理、中斷管理等)即可,而其他管理程序(如文件系統(tǒng)、網絡協(xié)議棧等)則盡可能放在內核以外。這些外部程序可以獨立運行,并對外部用戶程序提供操作系統(tǒng)服務,服務之間使用進程間通信機制(IPC)進行交互。如同面向對象程序設計帶來的好處一樣,微內核使操作系統(tǒng)內部結構變得簡單清晰。在內核以外的外部程序分別獨立運行,其間并不互相關聯(lián)。這樣,可以對這些程序分別進行維護和拆裝,只要遵循已經規(guī)定好的界面,就不會對其他程序有任何干擾。這使得程序代碼在維護上十分方便,體現(xiàn)了面向對象式軟件的結構特征。第十一頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)12微內核的結構也存在著不足之處。首先,程序代碼之間的相互隔離,使得整個系統(tǒng)喪失了許多優(yōu)化的機會。其次,部分資源浪費在外部進程之間的通信上,這樣,微內核結構在效率上必然低于傳統(tǒng)的單一內核結構,這些效率損失將作為結構精簡的代價。總體上說,在當前的硬件條件下,微內核在效率上的損失小于其在結構上獲得的收益,故而選取微內核成為操作系統(tǒng)的一大潮流。然而,Linux系統(tǒng)恰恰使用了單一內核結構。這是由于Linux是一個實用主義的操作系統(tǒng)。LinusTorvalds將代碼執(zhí)行效率作為自己操作系統(tǒng)的第一要務。在這樣的發(fā)展過程中,參與Linux系統(tǒng)開發(fā)的程序員大多數(shù)為世界各地的黑客們。比起結構的清晰,他們更加注重功能的強大和高效率的代碼。于是,他們將大量的精力花在優(yōu)化代碼上,而這樣的全局性優(yōu)化必然以損失結構精練作為代價,導致Linux中的每個部件都不能被輕易拆出,否則,必然破壞整體效率。雖然Linux是一個單一內核操作系統(tǒng),但它與傳統(tǒng)的單一內核UNIX操作系統(tǒng)不同。在普通的單一內核系統(tǒng)中,所有內核代碼都是被靜態(tài)編譯連入的。而在Linux中,可以動態(tài)裝入和卸載內核中的部分代碼。Linux中將這樣的代碼段稱為模塊(Module),并對模塊給予了強有力的支持。在Linux中,可以在需要時自動裝入和卸載模塊。Linux的內核為非搶占式的(Non-preemptive)。這就是說,Linux并不能通過改變優(yōu)先權來影響內核當前的執(zhí)行流程。Linux并不是一個“硬”實時操作系統(tǒng)。Linux操作系統(tǒng)的內核穩(wěn)定而高效,以獨占的方式執(zhí)行最底層任務,來保證其他程序的正常運行。它是整個操作系統(tǒng)的核心,具有獨特的性質。第十二頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)13進程管理進程是運行于自己的虛擬地址空間的一個程序??梢哉f,任何在Linux系統(tǒng)下運行的都是進程。Linux系統(tǒng)中包括下面幾種類型的進程。

交互進程:該進程是由shell控制和運行的。它既可以在前臺運行,也可以在后臺運行。

批處理進程:該進程不屬于某個終端,被提交到一個隊列中以便順序執(zhí)行。

守護進程:該進程只有在需要時才被喚起在后臺運行。它一般在Linux啟動時開始執(zhí)行。進程是動態(tài)的,在處理器執(zhí)行機器代碼時進程一直在變化。進程不但包括程序的指令和數(shù)據(jù),而且包括程序計數(shù)器和CPU的所有寄存器,以及存儲臨時數(shù)據(jù)的進程堆棧。由此可見,正在執(zhí)行的進程包括處理器當前的一切活動。Linux是一個多進程的操作系統(tǒng),每個進程都有自己的權限和任務,某一進程的失敗一般不會導致其他進程的失敗,進程之間可以通過由內核控制的機制相互通訊。在進程的整個運行期間,它將會用到各種系統(tǒng)資源,會用到CPU運行它的指令,需要物理內存保存它的數(shù)據(jù)。它可能打開和使用各種文件,直接或間接地使用系統(tǒng)中的各種物理設備。Linux系統(tǒng)內核必須了解進程本身的情況和進程所用到的各種資源,以便在多個進程之間合理地分配系統(tǒng)資源。系統(tǒng)中最為寶貴的資源是CPU,因為在一般情況下,一個系統(tǒng)只有一個CPU。Linux是一個多進程的操作系統(tǒng),所以,其他的進程必須等到正在運行的進程空閑CPU后才能運行。當正在運行的進程等待其他的系統(tǒng)資源時,Linux內核將取得CPU的控制權,并將CPU分配給其他正在等待的進程。內核中的調度算法決定將CPU分配給哪一個進程。第十三頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)14進程管理程序能夠進行進程的創(chuàng)建、激活、運行、阻塞、再運行、釋放,以及刪除。進程管理程序執(zhí)行下列操作:在多進程(或者任務、線程)系統(tǒng)中執(zhí)行每一個進程,使得進程狀態(tài)可以切換。進程的順序經過以下這些狀態(tài):“創(chuàng)建”、“就緒或者激活”、“產生”(創(chuàng)建且激活)、“運行”、“阻塞”、“再運行”、“完成”,以及“完成”之后的“就緒”(當進程中存在無限循環(huán)時)。最后,釋放或者刪除(在長進程中,阻塞和再運行可以發(fā)生很多次)。進程管理程序實現(xiàn)以下功能:

使進程能夠順序執(zhí)行或者在需要資源時發(fā)生阻塞,并使其在資源可用時繼續(xù)運行。

為進行資源管理(包括CPU上的進程調度)實現(xiàn)了與資源管理程序的邏輯鏈接。

限制某些資源只在某些進程間共享。

按照系統(tǒng)的資源分配機制分配資源。

管理系統(tǒng)中的進程和資源。第十四頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)151.進程與線程現(xiàn)在的嵌入式操作系統(tǒng)幾乎都被要求能夠與個人計算機上的操作系統(tǒng)一樣,提供多任務(Multitasking)功能。但是多數(shù)的嵌入式系統(tǒng)只有一個處理器,要完成這樣的要求,操作系統(tǒng)必須為這些不同的任務分配執(zhí)行時間,而這些任務就要輪流利用分配到的執(zhí)行時間來完成工作。為了方便管理這些任務,嵌入式操作系統(tǒng)會分別以一個執(zhí)行單位來看待一項工作或一個程序,這個執(zhí)行單位在不同的嵌入式操作系統(tǒng)中會有不同的名稱與意義,但是基本的思想都是為了讓不同的程序共同分享、使用有限的硬件資源,然后讓用戶在使用系統(tǒng)時,好像可以“同時”執(zhí)行多個應用程序。Linux采用所謂“繼承”的方法來進行資源分配。每個新的進程都必須先從父進程(ParentProcess)中去繼承一份系統(tǒng)資源,基本上就是子進程(ChildProcess)分配到另外一塊獨立的內存空間,然后從父進程的內存空間中把所有的數(shù)據(jù)完完全全拷貝過來,再通過參數(shù)的設置決定是否與父進程分享資源,并決定子進程屬于重優(yōu)先權值進程(HeavyWeightProcess)還是輕優(yōu)先權值進程(LightWeightProcess)。輕優(yōu)先權值進程在Linux里也稱為線程。第十五頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)162.進程的狀態(tài)不論采用何種方式,嵌入式操作系統(tǒng)必須管理多任務的執(zhí)行與切換,因為某一時刻真正被CPU執(zhí)行的任務只有一個,所以當同時存在許多不同的任務時,每個任務的狀態(tài)都不相同。一個進程在其生存期內,可處于一組不同的狀態(tài)下,稱為進程狀態(tài)。如圖2.2所示。操作系統(tǒng)會以一個特殊的數(shù)據(jù)結構來代表一個進程。這個特殊的數(shù)據(jù)結構會記錄一些重要的數(shù)據(jù),通常被稱為PCB(ProcessControlBlock)或TCB(TaskControlBlock)。它除了包含taskcontext(任務上下文)之外,還會記錄句柄、優(yōu)先級,以及一些進程的附屬數(shù)據(jù),這些數(shù)據(jù)提供了調度程序(Scheduler)調度時所需的全部信息。進程狀態(tài)就保存在TCB的state字段中。內核程序通過任務向量表對進程進行管理,每個進程在向量表中占有一項。在Linux系統(tǒng)中,任務向量表項是一個task_struct任務結構指針(在Linux中task和process互用)。任務數(shù)據(jù)結構定義在頭文件include/linux/sched.h中。這個數(shù)據(jù)結構也就是前面提到的TCB或PCB。當新的進程創(chuàng)建的時候,進程管理模塊從系統(tǒng)內存中分配一個新的task_struct,并增加到task向量表中。為了更容易查找,用current指針指向當前運行的進程。當一個進程在執(zhí)行時,CPU的所有寄存器中的值、進程的狀態(tài),以及堆棧中的內容被稱為該進程的上下文。當內核需要切換(switch)至另一個進程時,它就需要保存當前進程的所有狀態(tài),即保存當前進程的上下文,以便在再次執(zhí)行該進程時,能夠恢復到切換時的狀態(tài)并執(zhí)行下去。在Linux中,當前進程的上下文均保存在進程的任務數(shù)據(jù)結構中。第十六頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)17第十七頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)18

運行狀態(tài)(TASK_RUNNING),當進程正在被CPU執(zhí)行,或已經準備就緒隨時可由調度程序執(zhí)行時,稱該進程處于運行狀態(tài)(running)。進程可以在內核態(tài)運行,也可以在用戶態(tài)運行。當系統(tǒng)資源已經可用時,進程就被喚醒而進入準備運行狀態(tài),該狀態(tài)稱為就緒態(tài)。這些狀態(tài)在內核中表示方法相同,都被稱為處于TASK_RUNNING狀態(tài)。

可中斷睡眠狀態(tài)(TASK_INTERRUPTIBLE),當進程處于可中斷等待狀態(tài)時,系統(tǒng)不會調度該進程執(zhí)行。當系統(tǒng)產生一個中斷或者釋放了進程正在等待的資源,或者進程收到一個信號,都可以喚醒進程轉換到就緒狀態(tài)(運行狀態(tài))。

不可中斷睡眠狀態(tài)(TASK_UNINTERRUPTIBLE),不可中斷睡眠狀態(tài)與可中斷睡眠狀態(tài)類似。但處于該狀態(tài)的進程只有被使用wake_up()函數(shù)明確喚醒時,才能轉換到可運行的就緒狀態(tài)。

暫停狀態(tài)(TASK_STOPPED),當進程收到信號SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU時就會進入暫停狀態(tài)??上蚱浒l(fā)送SIGCONT信號讓進程轉換到可運行狀態(tài),正在調試的進程可以處在停止狀態(tài)。

僵死狀態(tài)(TASK_ZOMBIE),當進程已停止運行,但其父進程還沒有詢問其狀態(tài)時,則稱該進程處于僵死狀態(tài)。只有當進程從“內核運行態(tài)”轉移到“睡眠狀態(tài)”時,內核才會進行進程切換操作。在內核態(tài)下運行的進程不能被其他進程搶占,而且一個進程不能改變另一個進程的狀態(tài)。為了避免進程切換時造成內核數(shù)據(jù)錯誤,內核在執(zhí)行臨界區(qū)代碼時會禁止一切中斷。第十八頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)193.進程的創(chuàng)建進程的創(chuàng)建是指為創(chuàng)建的進程定義地址空間(存儲器塊),并為進程定義資源。Linux系統(tǒng)采用繼承的方式創(chuàng)建進程。進程管理程序在創(chuàng)建進程時分配TCB,并對它進行管理。TCB是進程管理程序使用的進程描述符。其他OS單元可以在必要的時候查詢進程的TCB。系統(tǒng)啟動的時候運行在核心態(tài),這時,只有一個進程:初始化進程。初始化進程是一個在處理器重啟時執(zhí)行存儲器指令,然后調用OS的進程。處理器隨后開始執(zhí)行創(chuàng)建的所有進程。像所有其他進程一樣,初始進程有一組用堆棧、寄存器等表示的機器狀態(tài)。當系統(tǒng)中的其他進程創(chuàng)建和運行時,這些信息存在初始進程的task_struct數(shù)據(jù)結構中。在系統(tǒng)初始化結束的時候,初始進程啟動一個核心線程(init)然后執(zhí)行空閑循環(huán),即什么也不做。也就是說,當處理器沒有什么可以做的時候,調度程序會運行這個空閑的進程。這個空閑進程的task_struct是惟一一個不是動態(tài)分配而是在核心連接的時候靜態(tài)定義的,為了不至于混淆,叫做init_task。init核心進程擁有進程標志符1,是系統(tǒng)的第一個真正的進程。它執(zhí)行系統(tǒng)的一些初始化的設置(比如,打開系統(tǒng)控制器,安裝根文件系統(tǒng)等),然后執(zhí)行系統(tǒng)初始化程序。根據(jù)系統(tǒng)的不同,初始化程序可能是/etc/init,/bin/init或/sbin/init其中之一。init程序使用/etc/inittab作為腳本文件創(chuàng)建系統(tǒng)中的新進程,這些新進程自身可能創(chuàng)建新的進程。例如,getty進程可能會在用戶試圖登錄的時候創(chuàng)建一個login的進程。系統(tǒng)中的所有進程都是init核心線程的后代。第十九頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)20新進程的創(chuàng)建是通過克隆舊的進程,或者說克隆當前的進程來實現(xiàn)的。一個新的任務是通過系統(tǒng)調用創(chuàng)建的(fork或clone),克隆發(fā)生在核心的核心態(tài)。在系統(tǒng)調用的最后,產生一個新的進程,等待調度程序選擇它運行(在新進程的創(chuàng)建未完成之前,為了防止這個還未處理完成的新建進程被調度函數(shù)執(zhí)行,應該將新進程狀態(tài)置為不可中斷的等待狀態(tài))。在系統(tǒng)的物理內存中為這個克隆進程的堆棧(用戶和核心)分配一個或多個物理的頁用于新的task_struct數(shù)據(jù)結構。一個進程標志符將會創(chuàng)建,它在系統(tǒng)的進程標志符組中是惟一的。新的task_struct進入task向量表中,舊的(當前的)進程的task_struct的內容拷貝到克隆的task_struct。克隆進程的時候,Linux允許兩個進程共享資源而不是擁有不同的拷貝,包括進程的文件,信號處理和虛擬內存。共享這些資源的時候,它們相應的count字段相應增減,這樣,Linux在兩個進程都停止使用之前不會釋放這些資源。例如,如果克隆的進程要共享虛擬內存,它的task_struct會包括一個指向原來進程的mm_struct指針,mm_struct的count域增加,表示當前共享它的進程。4.進程的調度Linux進程是搶占式的。被搶占的進程仍然處于TASK_RUNNING狀態(tài),只是暫時沒有被CPU運行。進程的搶占發(fā)生在進程處于用戶態(tài)執(zhí)行階段,在內核態(tài)執(zhí)行時是不能被搶占的。為了能讓進程有效地使用系統(tǒng)資源,又能使進程有較快的響應時間,Linux中采用基于優(yōu)先級排隊的調度策略。通常,核心會以分時(TimeSlicing)的觀念讓多任務共享CPU資源,即將CPU執(zhí)行的時間分成一段段的,每個程序會利用分配到的時間來執(zhí)行任務。每一段的執(zhí)行時間到了,就必須輪換下一個任務執(zhí)行。至于輪到哪一個任務來執(zhí)行,必須由核心的調度程序來決定。第二十頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)21在所有的進程中,部分運行于用戶態(tài),部分運行于核心態(tài)。底層的硬件支持這些狀態(tài)的方式各不相同,但是通常有一個安全機制從用戶態(tài)轉入核心態(tài)并轉回來。用戶態(tài)比核心態(tài)的權限低很多。每一次進程執(zhí)行一個系統(tǒng)調用,它都從用戶態(tài)切換到核心態(tài)并繼續(xù)執(zhí)行。這時,讓核心執(zhí)行這個進程。在Linux中,進程不是通過互相爭奪成為當前運行的進程,因為它們無法停止正在運行的其他進程而執(zhí)行自身。每一個進程在它必須等待一些系統(tǒng)事件的時候會放棄CPU。例如,一個進程可能不得不等待從一個文件中讀取一個字符,這個等待發(fā)生在核心態(tài)的系統(tǒng)調用中,進程使用了庫函數(shù)打開并讀文件,庫函數(shù)又執(zhí)行系統(tǒng)調用從打開的文件中讀入字節(jié)。這時,等候的進程會被掛起,另一個合適的進程將會被選擇執(zhí)行。由于進程經常調用系統(tǒng)調用,所以經常需要等待。由于即使進程執(zhí)行到需要等待,也有可能會用去不均衡的CPU時間,所以Linux使用搶先式的調度。用這種方案,每一個進程允許運行少量一段時間,通常為200毫秒,當這段時間過去,選擇另一個進程運行,原來的進程等待一段時間直到它又重新運行。這個時間段就叫做時間片。調度程序的任務就是選擇當前可運行的進程中最值得運行的一個進程。一個可以運行的進程是一個只等待CPU的進程。Linux使用合理而簡單的基于優(yōu)先級的調度算法在系統(tǒng)當前的進程中進行選擇。當它選擇了準備運行的新進程,就保存當前進程的狀態(tài)、與處理器相關的寄存器,以及其他需要保存的上下文信息到進程的task_struct數(shù)據(jù)結構中。然后恢復要運行的新的進程的狀態(tài)(又和處理器相關),把系統(tǒng)的控制交給這個進程。第二十一頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)22為了公平地在系統(tǒng)中所有可以運行(runnable)的進程之間分配CPU時間,調度程序在每一個進程的task_struct結構中保存了以下信息(參見Linux核心源文件kernel/sched.c中的函數(shù)schedule())。

Policy進程的調度策略。Linux有兩種類型的進程:普通和實時。實時進程比所有其他進程的優(yōu)先級高。如果有一個實時的進程準備運行,那么它總是先被運行。實時進程有兩種策略:循環(huán)或先進先出(roundrobinandfirstinfirstout)。在循環(huán)的調度策略下,每一個實時進程依次運行,而在先進先出的策略下,每一個可以運行的進程按照它在調度隊列中的順序運行,這個順序不會改變。

Priority進程的調度優(yōu)先級。也是指它允許運行時可以使用的時間量(jiffies)??梢酝ㄟ^系統(tǒng)調用或者renice命令來改變一個進程的優(yōu)先級。

Rt_priorityLinux支持實時進程。這些進程比系統(tǒng)中其他非實時的進程擁有更高的優(yōu)先級。這個域允許調度程序賦予每一個實時進程一個相對的優(yōu)先級。實時進程的優(yōu)先級可以用系統(tǒng)調用來修改。

Counter這是進程可以運行的時間量(jiffies)。進程啟動的時候等于優(yōu)先級(priority)的數(shù)值,每一個時鐘周期遞減1。調度程序從核心的多個地方運行。它可以在把當前進程放到等待隊列之后運行,也可以在系統(tǒng)調用之后進程從核心態(tài)返回用戶態(tài)之前運行。需要運行調度程序的另一個原因是系統(tǒng)時鐘剛好把當前進程的計數(shù)器(counter)置成0。第二十二頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)23每一次運行調度程序會完成以下工作:

kernelwork運行bottomhalfhandler并處理系統(tǒng)的調度任務隊列。

Currentpoccess在選擇另一個進程之前處理當前進程。

如果當前進程的調度策略是循環(huán)則將它放到運行隊列的最后。

如果任務是可中斷的而且它上次調度的時候收到過一個信號,將它的狀態(tài)變?yōu)镽UNNING。

如果當前進程超時,將它的狀態(tài)成為RUNNING。

如果當前進程的狀態(tài)為RUNNING則保持此狀態(tài)。

將不是RUNNING或者INTERRUPTIBLE的進程從運行隊列中刪除。這意味著當調度程序查找最值得運行的進程時不會考慮這樣的進程。

ProcessSelection查看運行隊列中的進程,查找最值得運行的進程。

SwapProcesses如果最值得運行的進程不是當前進程,當前進程必須被掛起,運行新的進程。一個進程運行時會使用系統(tǒng)的CPU、寄存器和物理內存。每一次它調用例程都通過寄存器或者堆棧傳遞參數(shù)、保存數(shù)值等??梢?,當調度程序運行的時候,它是在當前進程的上下文中運行。它可能處于特權模式:核心態(tài),但是它仍舊運行在當前進程的上下文中。當這個進程需要掛起時,它的所有機器狀態(tài),包括程序計數(shù)器(PC)和所有的處理器寄存器,必須存到進程的task_struct數(shù)據(jù)結構中。然后,加載新進程的所有機器狀態(tài)。這種操作依賴于系統(tǒng),不同CPU的實現(xiàn)方法也不相同,不過,通常都是通過一些硬件的幫助來實現(xiàn)。第二十三頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)24具體調度過程如下:schedule()函數(shù)首先掃描任務數(shù)組。通過比較每個就緒態(tài)(TASK_RUNNING)任務的運行時間遞減計數(shù)counter的值來確定當前哪個進程運行的時間最少。哪一個任務的counter值大,就表示運行時間還不長,于是就選中該進程,并使用任務切換宏函數(shù)切換到該進程運行。如果此時所有處于TASK_RUNNING狀態(tài)進程的時間片都已經用完,系統(tǒng)就會根據(jù)每個進程的優(yōu)先權值priority,對系統(tǒng)中所有進程(包括正在睡眠的進程)重新計算每個任務需要運行的時間片值counter。計算的公式是:counter

counter/2

priority然后schedule()函數(shù)重新掃描任務數(shù)組中所有處于TASK_RUNNING的狀態(tài),重復上述過程,直到選擇出一個進程為止。最后調用switch_to()執(zhí)行實際的進程切換操作。執(zhí)行實際進程切換的任務由switch_to()宏定義的一段匯編代碼完成。在進行切換之前,switch_to()首先檢查要切換到的進程是否就是當前進程,如果是,則什么也不做,直接退出。否則就把內核全局變量current置為新任務的指針,然后完成上下文的切換。第二十四頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)255.進程的終止當一個進程結束了運行或在半途終止了運行,那么內核就需要釋放該進程所占用的系統(tǒng)資源。這包括進程運行時打開的文件、申請的內存等。當一個用戶程序調用exit()系統(tǒng)調用時,則執(zhí)行內核函數(shù)do_exit()。該函數(shù)會首先釋放進程代碼段和數(shù)據(jù)段占用的內存頁面,關閉進程打開著的所有文件等。如果進程有子進程,則讓init進程作為其所有子進程的父進程,然后把進程狀態(tài)置為僵死狀態(tài)TASK_ZOMBIE,并向其原父進程發(fā)送SIGCHLD信號,通知其某個子進程已經終止。最后do_exit()調用調度函數(shù)去執(zhí)行其他進程。由此可見,在進程被終止時,它的任務數(shù)據(jù)結構仍然保留著,因為其父進程還需要使用其中的信息。子進程在執(zhí)行期間,父進程通常使用wait()或waitpid()函數(shù)等待其某個子進程終止。當?shù)却淖舆M程被終止并處于僵死狀態(tài)時,父進程就會把子進程運行所使用的時間累加到自己進程中。最終釋放已終止子進程任務數(shù)據(jù)結構所占用的內存頁面,并置空子進程在任務數(shù)組中占用的指針項。第二十五頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)26內存管理內存管理(MemoryManagement)系統(tǒng)是操作系統(tǒng)中最為重要的部分,內存管理程序子系統(tǒng)負責控制進程對硬件內存資源的訪問。這是通過硬件內存管理單元(MemoryManagementUnit,MMU)來完成的,該單元提供進程內存引用與計算機的物理內存之間的映射。內存管理程序子系統(tǒng)為每個進程都維護一個這樣的映射關系,使得兩個進程就可以訪問同一個虛擬內存地址,而實際使用的卻是不同的物理內存位置。此外,內存管理程序子系統(tǒng)支持交換,它把暫時不使用的內存頁面移出內存,存放到永久性存儲器(如硬盤存儲器)中,這樣,計算機就可以支持比物理內存要多的虛擬內存。內存管理程序提供以下一些功能:

大地址空間——用戶程序使用的內存數(shù)量可以超過物理上實際所有的內存數(shù)量。

保護——進程的內存是私有的,不能被其他進程所讀取和修改。而且,內存管理程序可以防止進程覆蓋代碼和只讀數(shù)據(jù)。

內存映射——可以把一個文件映射到虛擬內存區(qū)域,并把該文件當做內存來訪問。

對物理內存的公平訪問——內存管理程序確保所有的進程都能公平地訪問計算機的內存資源,這樣可以確保理想的系統(tǒng)性能。

共享內存——內存管理程序允許進程共享它們內存的一部分。第二十六頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)27虛擬內存的抽象模型:當處理器執(zhí)行一個程序時,它從內存中讀取指令并解碼執(zhí)行。當執(zhí)行這條指令時,處理器可能會需要在內存的某一個位置讀取或存儲數(shù)據(jù)。進程不管是讀取指令還是存取數(shù)據(jù)都要訪問內存。在一個虛擬內存系統(tǒng)中,所有程序涉及到的內存地址均為虛擬內存地址而不是機器的物理地址。處理器根據(jù)操作系統(tǒng)保存的一些信息將虛擬內存地址轉換為物理地址。為了讓這種轉換更容易地進行,虛擬內存和物理內存都分為大小固定的塊,叫做頁面(Page)。每一個頁面有一個惟一的頁面號,叫做PFN(PageFrameNumber)。Linux在AlphaAXP系統(tǒng)上使用8K字節(jié)的頁,而在Intelx86系統(tǒng)上使用4K字節(jié)的頁。在這種分頁方式下,一個虛擬內存地址由兩部分組成:一部分是位移地址,另一部分是PFN。每當處理器遇到一個虛擬內存地址時,都將會分離出位移地址和PFN地址。然后再將PFN地址轉換成物理地址,讀取其中的位移地址。處理器利用頁面表(PageTables)來完成上述的工作。圖2.3所示是進程X和進程Y的虛擬內存示意圖。兩個進程分別有自己的頁面表。這些頁面表用來將進程的虛擬內存頁映射到物理內存頁中。可以看出,進程X的虛擬內存頁0映射到了物理內存頁1,進程Y的虛擬內存頁1映射到了物理內存4。頁面表的每個入口一般都包括以下的內容:有效標志——此標志用于標明頁面表入口是否可以使用。物理頁面號——頁面表入口描述的物理頁面號。存取控制信息——用來描述頁面如何使用,例如,是否可寫,是否包括可執(zhí)行代碼等第二十七頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)28第二十八頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)29處理器讀取頁面表時,使用虛擬內存頁號作為頁面表的位移,例如,虛擬內存頁5是頁面表的第6個元素。在將虛擬內存地址轉換成物理內存地址時,處理器首先將虛擬內存地址分解為PFN和位移值。例如,在圖2.3中,一個頁面的大小是0x2000字節(jié)(十進制的8192),那么進程Y的一個虛擬內存地址0x2194將被分解成虛擬內存頁號PFN為1和位移0x194。然后處理器使用PFN作為進程頁面表的位移值來查找頁面表的入口。如果該入口是有效入口,處理器則從中取出物理內存的頁面號。如果入口是無效入口,處理器則產生一個頁面錯誤給操作系統(tǒng),并將控制權交給操作系統(tǒng)。假定此處是一個有效入口,則處理器取出物理頁面號,并乘以物理頁面的大小以便得到此物理頁面在內存中的地址,最后加上位移值。再看上面的例子:進程Y的PFN為1,映射到物理內存頁號為4,則此頁從0x8000(40x2000)開始,再加上位移0x194,得到最終的物理地址為0x8194。第二十九頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)301.按需裝入頁面(DemandPaging)由于物理內存要比虛擬內存小很多,所以操作系統(tǒng)一定要十分有效地利用系統(tǒng)的物理內存。一種節(jié)約物理內存的方法是只將執(zhí)行程序時正在使用的虛擬內存頁面裝入系統(tǒng)的物理頁面中。當一個進程試圖存取一個不在物理內存中的虛擬內存頁面時,處理器將會產生一個頁面錯誤給操作系統(tǒng)。如果發(fā)生頁面錯誤的虛擬內存地址為無效的地址,說明處理器正在存取一個它不應該存取的地址。這時,有可能是應用程序出現(xiàn)了某一方面的錯誤,在這種情況下,操作系統(tǒng)將會中止進程的運行,以防止系統(tǒng)中的其他進程受到破壞。如果發(fā)生頁面錯誤的虛擬內存地址為有效的地址,但此頁面當前并不在物理內存中,則操作系統(tǒng)必須從硬盤中將正確的頁面讀到系統(tǒng)內存中。相對而言,由于讀取硬盤要花費較長的時間,所以處理器必須等待,直到頁面讀取完畢。如果此時還有另外的進程等待運行,則操作系統(tǒng)將選擇一個進程運行。從硬盤中讀取的頁面將被寫入到一個空的物理內存頁中,然后在進程的頁面表中加入一個虛擬內存頁面號入口,此時進程就可以重新運行了。Linux系統(tǒng)使用按需裝入技術(DemandPaging)將可執(zhí)行代碼裝入到進程的虛擬內存中。每當一個命令執(zhí)行時,包括此命令的文件將被打開并映射到進程的虛擬內存中。此過程是通過修改描述進程內存映射的數(shù)據(jù)結構來實現(xiàn)的,通常被叫做內存映射(MemoryMapping)。但此時只有文件鏡像的第一部分被裝入系統(tǒng)的物理內存中,而鏡像的其他部分還保留在硬盤中。當此鏡像執(zhí)行時,處理器將產生頁面錯誤,Linux使用進程的內存映射表決定應該把鏡像的哪一部分裝入內存中執(zhí)行。第三十頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)312.交換(Swapping)當一個進程需要把一個虛擬內存頁面裝入物理內存而又沒有空閑時,操作系統(tǒng)必須廢棄物理內存中的一個頁面,為將要裝入的虛擬內存頁騰出空間。如果將要扔掉的物理內存頁一直沒有被改寫過,則操作系統(tǒng)將不保存此內存頁,而只是簡單地將它扔掉。當再次需要此內存頁時,再從文件鏡像中裝入。但是,如果此頁面已經被修改過,操作系統(tǒng)就需要把頁面的內容保存起來。這些頁面稱為“臟頁面”(dirtypage)。當它們從內存中移走時,將會被保存到一種叫做交換文件的特殊文件中。Linux系統(tǒng)使用一種叫做“最近最少使用”的技術(LeastRecentlyUsed,LRU)來決定把哪一個頁面從物理內存中移出。3.共享虛擬內存(SharedVirtualMemory)由于使用了虛擬內存,因此使幾個進程之間的內存共享變得很容易。每個內存的存取都要通過頁面表,而且每個內存都有自己的單獨的頁面表。如果希望兩個進程共享一個物理內存頁,只需將它們頁面表入口中的物理內存號設置為相同的物理頁面號即可,而且共享的物理頁不必存在共享它的進程的虛擬內存空間的同一個地方。4.訪問控制(AccessControl)頁面表中還包括了訪問控制信息。當處理器使用頁面表將進程的虛擬地址映射到物理地址的時候,可以方便地使用存取控制信息來檢查進程是否存取了它不該存取的信息。訪問控制信息放在PTE(PageTableEntry)中,而且與具體處理器相關。第三十一頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)325.高速緩存(Caches)為了獲得最大的系統(tǒng)效用,操作系統(tǒng)一般使用高速緩存來提高系統(tǒng)性能。Linux系統(tǒng)使用了以下幾種涉及高速緩存的內存管理方法。

BufferCache:緩沖區(qū)高速緩存,其中包含了由塊設備使用的數(shù)據(jù)緩沖區(qū)。

PageCache:頁面高速緩存,用來加速磁盤中文件鏡像和數(shù)據(jù)的存取。

SwapCache:交換文件,其中只保存那些被修改過的頁面。

HardwareCache:硬件高速緩存,通常是在處理器中,它保存著頁面表的入口。高速緩存的副作用在于Linux必須花大量時間和空間來維護這些高速緩存區(qū),如果這些高速緩存區(qū)崩潰,系統(tǒng)也會崩潰。6.頁的分配和回收(PageAllocationandDeallocation)系統(tǒng)在運行時會經常需要物理內存頁。例如,當一個文件鏡像從磁盤調入內存時,操作系統(tǒng)需要為它分配物理內存頁。當程序執(zhí)行完畢時,操作系統(tǒng)需要釋放內存頁。物理頁的另一個用途是存儲內核所需要的數(shù)據(jù)結構,例如,頁面表。頁面的分配和撤銷機制,以及所涉及的數(shù)據(jù)結構對內存管理來說是至關重要的。系統(tǒng)中所有的物理內存頁都包括在mem_map數(shù)據(jù)結構中,而mem_map是由mem_map_t結構組成的鏈表。mem_map_t在系統(tǒng)啟動時初始化,每個mem_map_t結構都描述了系統(tǒng)中的一個物理頁。第三十二頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)337.內存映射(MemoryMapping)當執(zhí)行一個文件鏡像時,可執(zhí)行鏡像的內容必須裝到進程的虛擬地址空間??蓤?zhí)行鏡像鏈接的共享庫也是一樣要裝入虛擬內存空間??蓤?zhí)行文件并不是真正地裝入物理內存空間,而只是簡單地鏈接到進程的虛擬內存。然后,隨著應用程序運行時的需要,可執(zhí)行鏡像才逐漸地裝入到物理內存中。這種將一個文件的鏡像和一個進程的虛擬內存地址空間連接起來的方法叫做內存映射。數(shù)據(jù)結構mm_struct代表每個進程的虛擬內存空間。它包含了正在執(zhí)行的鏡像的信息和一些指向vm_area_struct結構的指針,如圖2.4所示。每個vm_area_struct結構都描述了進程的虛擬內存的起始和結束位置、進程的存取權限,以及與內存有關的一系列的操作。這些操作是Linux系統(tǒng)在處理虛擬內存時將要用到的。當一個可執(zhí)行鏡像映射到一個進程的虛擬內存地址時,操作系統(tǒng)將創(chuàng)建一系列的數(shù)據(jù)結構vm_area_struct,每一個vm_area_struct代表可執(zhí)行鏡像的一部分。Linux系統(tǒng)支持多種標準虛擬內存操作,創(chuàng)建vm_area_struct時,相應的虛擬內存操作就會與vm_area_struct鏈接起來。第三十三頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)34第三十四頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)35文件系統(tǒng)管理Linux在設計時就考慮到支持許多不同的物理設備,甚至就一種特定類型的設備而言,例如,硬盤驅動器,在不同的硬件廠商之間也會存在許多接口上的差異。除了Linux所支持的物理設備以外,Linux還支持大量的邏輯文件系統(tǒng)。正因為它能支持許多邏輯文件系統(tǒng),所以Linux可以輕松地與其他操作系統(tǒng)進行互操作。Linux文件系統(tǒng)支持下列特性:

多個硬件設備——提供對許多不同的硬件設備的訪問。

多個邏輯文件系統(tǒng)——支持許多不同的邏輯文件系統(tǒng)。

多個可執(zhí)行格式——支持許多不同的可執(zhí)行文件格式(例如a.out、ELF、java)。

均一性——為所有的邏輯文件系統(tǒng),以及所有的硬件設備提供一個通用接口。

性能——提供對文件的高速訪問。

安全——不會丟失或毀壞數(shù)據(jù)。

保密性——限制用戶訪問文件的許可權限和分配給用戶的總的文件大小。目前,Linux系統(tǒng)支持大約15個文件系統(tǒng):EXT、EXT2、XIA、MINIX、UMSDOS、MSDOS、VFAT、PROC、SMB、NCP、ISO9660、SYSV、HPFS、AFFS和UFS。毫無疑問,Linux系統(tǒng)支持的文件系統(tǒng)還會增加。一個文件系統(tǒng)中不僅包括含有數(shù)據(jù)的文件,而且還存儲著文件系統(tǒng)的結構。文件系統(tǒng)中的信息必須是安全和保密的。第三十五頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)36Linux系統(tǒng)中的第一個文件系統(tǒng)是Minux,但它的文件名只能有14個字符,最大的文件長度是64MB。也正因此,1992年4月引進了第一個專門為Linux設計的文件系統(tǒng)——ext(extendedfilesystem),但ext的功能還是有限。最后在1993年又推出了一個新的文件系統(tǒng)——EXT2。當Linux引進ext文件系統(tǒng)時有了一個重大的改進:真正的文件系統(tǒng)從操作系統(tǒng)和系統(tǒng)服務中分離出來,在它們之間使用了一個接口層——虛擬文件系統(tǒng)VFS(VirtualFilesystem)。VFS允許Linux支持多種不同的文件系統(tǒng),每個文件系統(tǒng)都要提供給VFS一個相同的接口。這樣,所有的文件系統(tǒng)對系統(tǒng)內核和系統(tǒng)中的程序來說看起來都是相同的。Linux系統(tǒng)中的VFS層使得用戶可以同時在系統(tǒng)中透明地掛接很多不同的文件系統(tǒng)。在Linux系統(tǒng)中,每一個單獨的文件系統(tǒng)都是代表整個系統(tǒng)的樹狀結構的一部分。當掛接一個新的文件系統(tǒng)時,Linux把它添加到這個樹狀的文件系統(tǒng)中。所有系統(tǒng)中的文件系統(tǒng),不管是什么類型,都掛接到一個目錄下,并隱藏目錄中原有的內容。這個目錄叫做掛接目錄或者掛接點。當文件系統(tǒng)卸載時,目錄中的原有內容將再一次地顯示出來。磁盤在初始化時被劃分成幾個邏輯分區(qū),每一個邏輯分區(qū)可以使用一種文件系統(tǒng),例如,EXT2文件系統(tǒng)。文件系統(tǒng)把存儲在物理驅動器中的文件組織成一個樹狀的目錄結構,可以存儲文件的設備稱為塊設備。Linux文件系統(tǒng)把這些塊設備當做簡單的線形塊的集合,而不管物理磁盤的結構如何。而將讀寫某一個設備塊的請求轉換成特定的磁道、扇區(qū)和柱面是通過設備的驅動程序實現(xiàn)的。因此,不同的設備控制器控制的不同設備中的不同文件系統(tǒng)在Linux中都可以同樣地使用。文件系統(tǒng)甚至可以不在當?shù)氐南到y(tǒng)中,也就是說,文件系統(tǒng)可以通過網絡遠程連接到本地磁盤上。第三十六頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)37當文件系統(tǒng)被作為子目錄掛裝時,在該設備上的所有目錄和文件都將被視為掛裝點的子目錄。虛擬文件系統(tǒng)的用戶不需要考慮哪種邏輯文件系統(tǒng)實現(xiàn)了目錄樹的哪個部分,也無需考慮哪個物理設備包含這些邏輯文件系統(tǒng)。這種抽象性在選擇物理設備和邏輯文件系統(tǒng)時,提供了很大的方便,而這種方便性是Linux操作系統(tǒng)成功的重要因素之一。VFS能高速度及高效率地存取系統(tǒng)中的文件,與此同時它還得確保文件和數(shù)據(jù)的正確性。這兩個目標有時可能相互矛盾。由于VFS在每個文件系統(tǒng)掛接和使用時,把文件系統(tǒng)的有關信息暫時保存在內存中,所以當內存中的信息改變時,例如,創(chuàng)建、寫入和刪除目錄和文件時,系統(tǒng)要保證正確地升級文件系統(tǒng)中相關的內容。如果了解在系統(tǒng)內核中運行的文件系統(tǒng)的數(shù)據(jù)結構,那么也就能比較容易地理解文件系統(tǒng)讀取的數(shù)據(jù)塊的情況。系統(tǒng)緩存中最重要的就是緩沖區(qū)緩存,它被集成到每個單獨的文件系統(tǒng)存取它們的塊設備所使用的方法中。每當系統(tǒng)存取數(shù)據(jù)塊時,數(shù)據(jù)塊被放入到緩沖區(qū)緩存中,并且依照它們的狀態(tài)保存到各種各樣的隊列中。緩沖區(qū)緩存中不僅保存了數(shù)據(jù)緩沖區(qū),而且還可以幫助管理與塊設備驅動程序之間的異步接口。為了支持虛擬文件系統(tǒng),Linux使用了索引節(jié)點的概念。Linux使用索引節(jié)點來表示塊設備上的文件。索引節(jié)點中包含了一些操作,根據(jù)文件所駐留的邏輯系統(tǒng)和物理系統(tǒng)的不同,這些操作的實現(xiàn)方法也會有所變化。從這層意義上講,索引節(jié)點是虛擬的。索引節(jié)點接口使所有的文件在其他Linux子系統(tǒng)看起來都是一樣的。索引節(jié)點可以用做一個存儲位置,存儲磁盤上與某個打開的文件相關的所有信息。索引節(jié)點存儲相關緩沖、以塊為單位的文件總長度,以及文件偏移量和設備塊之間的映射。第三十七頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)381.EXT2文件系統(tǒng)EXT2文件系統(tǒng)是Linux系統(tǒng)中最為成功的文件系統(tǒng),各種Linux的系統(tǒng)發(fā)布都將EXT2文件系統(tǒng)作為操作系統(tǒng)的基礎。EXT2文件系統(tǒng)中的數(shù)據(jù)是以數(shù)據(jù)塊的方式存儲在文件中的。這些數(shù)據(jù)塊具有同樣的大小,并且其大小可以在EXT2創(chuàng)建時設定,每一個文件的長度都要補足到塊的整數(shù)倍。EXT2通過使用索引節(jié)點(inode)數(shù)據(jù)結構來描述系統(tǒng)中的每一個文件。索引節(jié)點描述了文件中的數(shù)據(jù)占用了哪一個數(shù)據(jù)塊,以及文件的存取權限、文件的修改時間和文件類型等信息。EXT2文件系統(tǒng)中的每一個文件都只有一個索引節(jié)點,而每一個索引節(jié)點都有一個惟一的標志符。文件系統(tǒng)中的所有的索引節(jié)點都保存在索引節(jié)點表中。EXT2中的目錄只是一些簡單的特殊文件(它們也使用索引節(jié)點描述),這些文件中包含指向目錄入口的索引節(jié)點的指針。對于一個文件系統(tǒng)來說,某一個塊設備只是一系列可以讀寫的數(shù)據(jù)塊。文件系統(tǒng)無需關心數(shù)據(jù)塊在設備中的具體位置,因為這是設備驅動程序的工作。每當文件系統(tǒng)需要從塊設備中讀取數(shù)據(jù)時,它就要求設備驅動程序讀取整數(shù)數(shù)目的數(shù)據(jù)塊。EXT2文件系統(tǒng)將它所占用的設備的邏輯分區(qū)分成了數(shù)據(jù)塊組。每一個數(shù)據(jù)塊組都包含一些有關整個文件系統(tǒng)的信息,以及真正的文件和目錄的數(shù)據(jù)塊。在EXT2文件系統(tǒng)中索引節(jié)點是一切的基礎,文件系統(tǒng)中的每一個文件和目錄都使用一個惟一的索引節(jié)點。每一個數(shù)據(jù)塊組中的索引節(jié)點都保存在索引節(jié)點表中。數(shù)據(jù)塊組中還有一個索引節(jié)點位圖,它用來記錄系統(tǒng)中已分配和未分配的索引節(jié)點。第三十八頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)39下面是EXT2的索引節(jié)點的一些主要的字段。

mode這里保存兩個信息:一個是此索引節(jié)點描述的是什么,另一個是用戶擁有的權限。例如,對于EXT2,一個索引節(jié)點可以描述文件、目錄、符號連接、塊設備、字符設備,以及FIFO結構。

OwnerInformation這是文件或目錄所有者的用戶和組標志符。這使得文件系統(tǒng)可以正確地授權某種存取操作。

Size文件的字節(jié)大小。

Timestamps索引節(jié)點建立的時間和索引節(jié)點最后修改的時間。

Datablocks指向存儲此索引節(jié)點描述文件的數(shù)據(jù)塊的指針。前12個指針是指向存儲數(shù)據(jù)的物理數(shù)據(jù)塊的指針,而后3個指針則包括不同級別的間接指針。例如,兩級指針指向一個指向其他指針塊的指針塊,這意味著小于或者等于12個數(shù)據(jù)塊的文件的存取速度要高于多于12個數(shù)據(jù)塊的文件。超級塊(Superblock)存儲著描述文件系統(tǒng)的大小和形狀的基本信息。文件系統(tǒng)的管理員可以使用其中的信息來使用和維護文件系統(tǒng)。一般情況下,當文件系統(tǒng)掛接時,系統(tǒng)只讀取數(shù)據(jù)塊組0中的超級塊,但每一個數(shù)據(jù)塊組中都包含一個超級塊的副本,以防系統(tǒng)崩潰時使用。第三十九頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)402.虛擬文件系統(tǒng)(VFS)如圖2.5所示為Linux系統(tǒng)內核中的VFS和實際文件系統(tǒng)之間的關系。VFS必須管理同時掛接在系統(tǒng)上的不同的文件系統(tǒng)。VFS通過使用描述整個VFS的數(shù)據(jù)結構和描述實際掛接的文件系統(tǒng)的數(shù)據(jù)結構來管理這些不同的文件系統(tǒng)。這里易于混淆的是,VFS和EXT2文件系統(tǒng)一樣使用超級塊和索引節(jié)點來描述系統(tǒng)中的文件。與EXT2中的索引節(jié)點一樣,VFS的索引節(jié)點用來描述系統(tǒng)中的文件和目錄。當一個文件系統(tǒng)初始化時,它將在VFS中登記。這些過程在操作系統(tǒng)初始化時完成。實際的文件系統(tǒng)或者內建到操作系統(tǒng)內核中,或者作為可裝入模塊在需要時裝入。當一個基于塊設備的文件系統(tǒng)掛接時,當然也包括根文件系統(tǒng),VFS首先要讀取它的超級塊。每一個文件系統(tǒng)的超級塊讀取程序都必須先清楚文件系統(tǒng)的結構,然后把有關的信息添加到VFS的超級塊數(shù)據(jù)結構中。VFS中保存了系統(tǒng)中掛接的文件系統(tǒng)的鏈表,以及這些文件系統(tǒng)對應的VFS超級塊。每一個VFS超級塊都包含一些信息和指向一些執(zhí)行特別功能的子程序的指針。例如,代表掛接的EXT2文件系統(tǒng)的VFS超級塊包含了一個指向EXT2索引節(jié)點讀取程序的指針。這個EXT2索引節(jié)點讀取程序,與其他文件系統(tǒng)索引節(jié)點的讀取程序一樣,把信息添加到VFS索引節(jié)點中的字段中。每一個VFS超級塊都包含一個指向文件系統(tǒng)中第一個VFS索引節(jié)點的指針。對于根文件系統(tǒng)來說,第一個VFS索引節(jié)點是代表根目錄(/)的索引節(jié)點。這種對應關系對于EXT2文件系統(tǒng)來說十分有效,但對于其他的文件系統(tǒng)則效果一般。第四十頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)41當系統(tǒng)中的進程存取目錄和文件時,需要調用系統(tǒng)中的子程序來遍歷搜索系統(tǒng)中的VFS索引節(jié)點。例如,鍵入ls或者cat命令將導致VFS搜索整個文件系統(tǒng)中的VFS索引節(jié)點。因為系統(tǒng)中的每一個文件和目錄都由一個索引節(jié)點來表示,那么有些索引節(jié)點將經常會被重復地搜索。這些索引節(jié)點將保存在索引節(jié)點緩存中,這樣將加快以后的存取速度。如果要找的索引節(jié)點不在索引節(jié)點緩存中,那么進程將調用一個特殊的系統(tǒng)程序來讀取相應的索引節(jié)點。讀取索引節(jié)點后,此索引節(jié)點將放在索引節(jié)點緩存中。最少用到的索引節(jié)點將被交換出索引節(jié)點緩存。第四十一頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)42設備管理操作系統(tǒng)的一個功能就是將用戶和系統(tǒng)的硬件特性隔離。例如,虛擬文件系統(tǒng)(VFS)使得系統(tǒng)上掛接的文件系統(tǒng)具有相同的接口,使用戶不必關心底層的硬件設備。計算機系統(tǒng)中的物理設備都有自己的硬件控制器。例如,鍵盤、鼠標和串行口是由SuperIO芯片控制的;IDE硬盤是由IDE控制器控制的,等等。每一個硬件控制器都有自己的控制及狀態(tài)寄存器(CSR),而且隨設備的不同而不同。CSR用來啟動和停止設備、初始化設備和診斷設備錯誤。設備驅動程序一般集成在操作系統(tǒng)內核,這樣,不同的應用程序就可以共享這些代碼。設備驅動程序實際是處理或操作硬件控制器的軟件,從本質上講,它們是內核中具有高特權級的、駐留內存的、可共享的底層硬件處理例程。設備驅動程序的一個基本特點就是對設備的抽象處理。系統(tǒng)中的所有硬件設備看起來都與一般的文件一樣,它們可以使用處理文件的標準系統(tǒng)調用來打開、關閉和讀寫。系統(tǒng)中的每一個設備都由一個設備文件來代表,例如,主IDE硬盤的設備文件是/dev/hda。對于塊設備和字符設備來說,這些設備文件可以使用mknod命令創(chuàng)建。新建的設備文件使用主設備號和從設備號來描述此設備。網絡設備的設備文件是當系統(tǒng)查找到網絡設備并初始化網絡控制器之后才建立的。一個設備驅動程序控制的所有設備有一個相同的主設備號,通過不同的從設備號來區(qū)分設備和它們的控制器。例如,主IDE硬盤的每一個分區(qū)都有一個不同的從設備號,這樣,主IDE硬盤的第二個分區(qū)的設備文件是/dev/hda2。Linux系統(tǒng)使用主設備號和系統(tǒng)中的一些表來將系統(tǒng)調用中使用的設備文件映射到設備驅動程序中。第四十二頁,共六十一頁,編輯于2023年,星期日第2章嵌入式LINUX操作系統(tǒng)43Linux系統(tǒng)支持三種類型的硬件設備:字符設備、塊設備和網絡設備。其中與文件子系統(tǒng)相關的兩種類型是字符設備和塊設備。字符設備是直接讀取的,不必使用緩沖區(qū),但是必須以串行的順序依次訪問。例如,系統(tǒng)的串行口/dev/cua0和/dev/cua1。塊設備每次只能讀取一定大小的塊的倍數(shù),通常一塊是512字節(jié)或者1024字節(jié)。塊設備通過緩沖區(qū)讀寫,并且可以隨機地讀寫。塊設備可以通過它們的設備文件存取,但通常是通過文件系統(tǒng)存取。只有塊設備支持掛接的文件系統(tǒng)。網絡設備是通過

溫馨提示

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

最新文檔

評論

0/150

提交評論