嵌入式系統(tǒng)第六章嵌入式Linux操作系統(tǒng)課件_第1頁(yè)
嵌入式系統(tǒng)第六章嵌入式Linux操作系統(tǒng)課件_第2頁(yè)
嵌入式系統(tǒng)第六章嵌入式Linux操作系統(tǒng)課件_第3頁(yè)
嵌入式系統(tǒng)第六章嵌入式Linux操作系統(tǒng)課件_第4頁(yè)
嵌入式系統(tǒng)第六章嵌入式Linux操作系統(tǒng)課件_第5頁(yè)
已閱讀5頁(yè),還剩82頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第5章嵌入式Linux操作系統(tǒng)

5.1與Linux相關(guān)術(shù)語(yǔ)GNUGUN項(xiàng)目(GNUProject)開(kāi)始于1984年,主要由自由軟件基金(FreeSoftwareFoundation——FSF)資助的一個(gè)項(xiàng)目,目標(biāo)是開(kāi)發(fā)一個(gè)自由的、UNIX類型的操作系統(tǒng),稱為GNU系統(tǒng)。GNU是“GNU’sNotUNIX”的首字母的遞歸縮寫(xiě)。GPL所有的GNU軟件和派生工作均遵循GNU通用公共許可證,即GPL。5.1與Linux相關(guān)術(shù)語(yǔ)GNULGPL(LibraryGeneralPublicLicense——程序庫(kù)公共許可證)允許用戶在自己的應(yīng)用程序中使用程序庫(kù),即使不公開(kāi)自己的源代碼。用戶必須能夠獲得在應(yīng)用程序中使用的程序庫(kù)的源代碼,并且允許用戶對(duì)這些程序庫(kù)進(jìn)行修改。遵循LGPL的一種方法是,隨應(yīng)用程序一起發(fā)布目標(biāo)代碼以及可以將這些目標(biāo)程序和受LGPL保護(hù)的程序庫(kù)鏈接起來(lái)的makefile文件。遵循LGPL的另一種比較好的方法是使用動(dòng)態(tài)鏈接。FSF:

FreeSoftwareFoundation

自由軟件基金會(huì)Linux具有的特點(diǎn)1、完全免費(fèi)2、開(kāi)放型3、支持多用戶訪問(wèn)和多任務(wù)編程4、良好的用戶界面5、支持多種文件系統(tǒng)6、采用虛擬內(nèi)存管理技術(shù)7、設(shè)備獨(dú)立性8、豐富的網(wǎng)絡(luò)功能9、可靠的系統(tǒng)安全10、良好的可移植性完整的Linux架構(gòu)圖作為一個(gè)完成的操作系統(tǒng),Linux具有穩(wěn)定而強(qiáng)大的功能,想要訪問(wèn)任何非自己的存儲(chǔ)器空間的進(jìn)程只能通過(guò)系統(tǒng)調(diào)用來(lái)達(dá)成。一般進(jìn)程是處于用戶模式底下,而運(yùn)行系統(tǒng)調(diào)用時(shí)會(huì)被切換成內(nèi)核模式,所有的特殊指令只能在內(nèi)核模式運(yùn)行,此措施讓內(nèi)核可以完美管理系統(tǒng)內(nèi)部與外部設(shè)備,并且拒絕無(wú)權(quán)限的進(jìn)程提出的請(qǐng)求。因此理論上任何應(yīng)用程序運(yùn)行時(shí)的錯(cuò)誤,都不可能讓系統(tǒng)崩潰。

5.2.3進(jìn)程管理進(jìn)程的基本概念

進(jìn)程就是運(yùn)行中的程序。一個(gè)運(yùn)行著的程序,可能有多個(gè)進(jìn)程。對(duì)于進(jìn)程來(lái)說(shuō),可以看成是一個(gè)具有獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次可以并發(fā)執(zhí)行的運(yùn)行活動(dòng),是處于活動(dòng)狀態(tài)的計(jì)算機(jī)程序。進(jìn)程的屬性進(jìn)程的定義:一個(gè)進(jìn)程是一個(gè)程序的一次執(zhí)行的過(guò)程;程序是靜態(tài)的,它是一些保存在磁盤(pán)上的可執(zhí)行的代碼和數(shù)據(jù)集合;進(jìn)程是一個(gè)動(dòng)態(tài)的概念,它是Linux系統(tǒng)的基本的調(diào)度單位。一個(gè)進(jìn)程由如下元素組成:程序讀取的上下文,它表示程序讀取執(zhí)行的狀態(tài)。程序當(dāng)前執(zhí)行的目錄。程序服務(wù)的文件和目錄。程序訪問(wèn)的權(quán)限。內(nèi)存和其他分配給進(jìn)程的系統(tǒng)資源。Linux進(jìn)程中最知名的屬性就是它的進(jìn)程號(hào)(ProcessIdenityNumber,PID)和它的父進(jìn)程號(hào)(ParentProcessID,PPID)。PID、PPID都是非零正整數(shù)。一個(gè)PID唯一地標(biāo)識(shí)一個(gè)進(jìn)程。一個(gè)進(jìn)程創(chuàng)建新進(jìn)程稱為創(chuàng)建了子進(jìn)程(ChildProcess)。相反地,創(chuàng)建子進(jìn)程的進(jìn)程稱為父進(jìn)程。所有進(jìn)程追溯其祖先最終都會(huì)落到進(jìn)程號(hào)為1的進(jìn)程身上,這個(gè)進(jìn)程叫做init進(jìn)程,是內(nèi)核自舉后第一個(gè)啟動(dòng)的進(jìn)程。init進(jìn)程扮演終結(jié)父進(jìn)程的角色。因?yàn)閕nit進(jìn)程永遠(yuǎn)不會(huì)被終止,所以系統(tǒng)總是可以確信它的存在,并在必要的時(shí)候以它為參照。

進(jìn)程狀態(tài) 進(jìn)程在生存周期中的各種狀態(tài)及狀態(tài)的轉(zhuǎn)換。

Linux系統(tǒng)的進(jìn)程狀態(tài)模型的各種狀態(tài):

用戶狀態(tài):進(jìn)程在用戶狀態(tài)下運(yùn)行的狀態(tài)。

內(nèi)核狀態(tài):進(jìn)程在內(nèi)核狀態(tài)下運(yùn)行的狀態(tài)。

內(nèi)存中就緒:進(jìn)程沒(méi)有執(zhí)行,但處于就緒狀態(tài),只要內(nèi)核調(diào)度它,就可以執(zhí)行。

內(nèi)存中睡眠:進(jìn)程正在睡眠并且進(jìn)程存儲(chǔ)在內(nèi)存中,沒(méi)有被交換到SWAP設(shè)備。

就緒且換出:進(jìn)程處于就緒狀態(tài),但是必須把它換入內(nèi)存,內(nèi)核才能再次調(diào)度它運(yùn)行。

睡眠且換出:進(jìn)程正在睡眠,且被換出內(nèi)存。

被搶先:進(jìn)程從內(nèi)核狀態(tài)返回用戶狀態(tài)時(shí),內(nèi)核搶先于它做了上下文切換,調(diào)度了另一個(gè)進(jìn)程。原先這個(gè)進(jìn)程就處于被搶先狀態(tài)。

創(chuàng)建狀態(tài):進(jìn)程剛被創(chuàng)建。該進(jìn)程存在,但既不是就緒狀態(tài),也不是睡眠狀態(tài)。這個(gè)狀態(tài)是除了進(jìn)程0以外的所有進(jìn)程的最初狀態(tài)。

僵死狀態(tài)(zombie):進(jìn)程調(diào)用exit結(jié)束,進(jìn)程不再存在,但在進(jìn)程表項(xiàng)中仍有記錄,該記錄可由父進(jìn)程收集。進(jìn)程的創(chuàng)建與結(jié)束

在Linux系統(tǒng)中,通常使用fork()系統(tǒng)調(diào)用用來(lái)復(fù)制一個(gè)現(xiàn)有進(jìn)程,從而創(chuàng)建一個(gè)全新的進(jìn)程。被復(fù)制的進(jìn)程被稱為父進(jìn)程,新產(chǎn)生的進(jìn)程被稱為子進(jìn)程。 為了方便用戶處理父進(jìn)程與子進(jìn)程之間的一些事物,Linux允許父進(jìn)程在創(chuàng)建了進(jìn)程之后,通過(guò)調(diào)用wait()先進(jìn)入等待狀態(tài),以使子進(jìn)程先運(yùn)行,然后再?zèng)Q定自己的進(jìn)一步行為,這成為父進(jìn)程的阻塞方式。 進(jìn)程的結(jié)束可以使用exit()系統(tǒng)調(diào)用,無(wú)論在執(zhí)行到什么位置,只要執(zhí)行到exit系統(tǒng)調(diào)用,進(jìn)程會(huì)停止所有操作并將其占用的資源釋放掉。進(jìn)程的創(chuàng)建與結(jié)束 有一個(gè)更簡(jiǎn)單的執(zhí)行其他程序的函數(shù)system,參數(shù)string傳遞給一個(gè)命令解釋器(一般為sh)執(zhí)行,即string被解釋為一條命令,由sh執(zhí)行該命令。

除了system之外,系統(tǒng)調(diào)用exec來(lái)執(zhí)行一個(gè)可執(zhí)行文件,來(lái)代替當(dāng)前進(jìn)程的執(zhí)行映像。

系統(tǒng)調(diào)用exit的功能是終止發(fā)出調(diào)用的進(jìn)程。

父進(jìn)程和子進(jìn)程的關(guān)系是管理和被管理的關(guān)系,當(dāng)父進(jìn)程終止時(shí),子進(jìn)程也隨之而終止。但子進(jìn)程終止時(shí),父進(jìn)程并不一定終止。在Linux中,進(jìn)程是以進(jìn)程號(hào)PID(ProcessID)作為標(biāo)示。任何對(duì)進(jìn)程進(jìn)行的操作都要給與其相應(yīng)的PID號(hào)。每個(gè)進(jìn)程都屬于一個(gè)用戶,進(jìn)程要配備其所屬的用戶編號(hào)UID。此外,每個(gè)進(jìn)程都屬于多個(gè)用戶組,所以進(jìn)程還要配備其歸屬的用戶組編號(hào)GID的數(shù)組。進(jìn)程運(yùn)行的環(huán)境成為進(jìn)程上下文。Linux中進(jìn)程的上下文由進(jìn)程控制塊PCB(ProcessControlBlock)、正文段、數(shù)據(jù)段以及用戶堆棧組成。其中,正文段存放該進(jìn)程的可執(zhí)行代碼,數(shù)據(jù)段存放進(jìn)程中靜態(tài)產(chǎn)生的數(shù)據(jù)結(jié)構(gòu),而PCB包括進(jìn)程的編號(hào)、狀態(tài)、優(yōu)先級(jí)以及正文段和數(shù)據(jù)段中數(shù)據(jù)分布的大概情況。一個(gè)稱作進(jìn)程表(ProcessTable)的鏈表結(jié)構(gòu)將系統(tǒng)中所有的PCB塊聯(lián)系起來(lái)

。啟動(dòng)一個(gè)進(jìn)程有兩個(gè)主要途徑:手工啟動(dòng)和調(diào)度啟動(dòng),后者是事先進(jìn)行設(shè)置,根據(jù)用戶要求自行啟動(dòng)。由用戶輸入命令,直接啟動(dòng)一個(gè)進(jìn)程便是手工啟動(dòng)進(jìn)程。但手工啟動(dòng)進(jìn)程又可以分為很多種,根據(jù)啟動(dòng)的進(jìn)程類型不同、性質(zhì)不同,實(shí)際結(jié)果也不一樣。(1)前臺(tái)啟動(dòng) 前臺(tái)啟動(dòng)是手工啟動(dòng)一個(gè)進(jìn)程的最常用的方式。用戶鍵入一個(gè)命令“df”,就已經(jīng)啟動(dòng)了一個(gè)進(jìn)程,而且是一個(gè)前臺(tái)的進(jìn)程。(2)后臺(tái)啟動(dòng) 直接從后臺(tái)手工啟動(dòng)一個(gè)進(jìn)程用得比較少一些,除非是該進(jìn)程甚為耗時(shí),且用戶也不急著需要結(jié)果。進(jìn)程的狀態(tài)和調(diào)度

一般來(lái)說(shuō),所有進(jìn)程都要經(jīng)歷三種狀態(tài),即運(yùn)行態(tài)、就緒態(tài)和阻塞態(tài)

進(jìn)程的調(diào)度

為了讓Linux來(lái)管理系統(tǒng)中的進(jìn)程,每個(gè)進(jìn)程用一個(gè)task_struct數(shù)據(jù)結(jié)構(gòu)來(lái)表示(任務(wù)與進(jìn)程在Linux中可以混用)。數(shù)組task包含指向系統(tǒng)中所有task_struct結(jié)構(gòu)的指針。這意味著系統(tǒng)中的最大進(jìn)程數(shù)目受task數(shù)組大小的限制,缺省值一般為512。創(chuàng)建新進(jìn)程時(shí),Linux將從系統(tǒng)內(nèi)存中分配一個(gè)task_struct結(jié)構(gòu)并將其加入task數(shù)組。當(dāng)前運(yùn)行進(jìn)程的結(jié)構(gòu)用current指針來(lái)指示。

Linux還支持實(shí)時(shí)進(jìn)程。這些進(jìn)程必須對(duì)外部時(shí)間作出快速反應(yīng)(這就是“實(shí)時(shí)”的意思),系統(tǒng)將區(qū)分對(duì)待這些進(jìn)程和其他進(jìn)程。雖然task_struct數(shù)據(jù)結(jié)構(gòu)龐大而復(fù)雜,但它可以分成一些功能組成部分:State

進(jìn)程在執(zhí)行過(guò)程中會(huì)根據(jù)環(huán)境來(lái)改變state。Scheduling

Information

調(diào)度器需要這些信息以便判定系統(tǒng)中哪個(gè)進(jìn)程最迫切需要運(yùn)行。Identifiers

系統(tǒng)中每個(gè)進(jìn)程都有進(jìn)程標(biāo)志。進(jìn)程標(biāo)志并不是task數(shù)組的索引,它僅僅是個(gè)數(shù)字。Inter-Process

Communication

Linux支持經(jīng)典的UnixIPC機(jī)制。Links

Linux系統(tǒng)中所有進(jìn)程都是相互聯(lián)系的。Times

and

Timers

核心需要記錄進(jìn)程的創(chuàng)建時(shí)間以及在其生命期中消耗的CPU時(shí)間。File

system

進(jìn)程可以自由地打開(kāi)或關(guān)閉文件,進(jìn)程的task_struct結(jié)構(gòu)中包含一個(gè)指向每個(gè)打開(kāi)文件描敘符的指針以及指向兩個(gè)VFS

inode的指針。Virtual

memory

多數(shù)進(jìn)程都有一些虛擬內(nèi)存(核心線程和后臺(tái)進(jìn)程沒(méi)有),Linux核心必須跟蹤虛擬內(nèi)存與系統(tǒng)物理內(nèi)存的映射關(guān)系。Processor

Specific

Context

進(jìn)程可以認(rèn)為是系統(tǒng)當(dāng)前狀態(tài)的總和。Linux使用用戶和組標(biāo)志符來(lái)檢查對(duì)系統(tǒng)中文件和可執(zhí)行映象的訪問(wèn)權(quán)限。Linux系統(tǒng)中所有的文件都有所有者和允許的權(quán)限,這些權(quán)限描敘了系統(tǒng)使用者對(duì)文件或者目錄的使用權(quán)?;镜臋?quán)限是讀、寫(xiě)和可執(zhí)行,這些權(quán)限被分配給三類用戶:文件的所有者,屬于相同組的進(jìn)程以及系統(tǒng)中所有進(jìn)程。每類用戶具有不同的權(quán)限,例如一個(gè)文件允許其擁有者讀寫(xiě),但是同組的只能讀而其他進(jìn)程不允許訪問(wèn)。

進(jìn)程調(diào)度機(jī)制的設(shè)計(jì),還對(duì)系統(tǒng)復(fù)雜性有著極大的影響,常常會(huì)由于實(shí)現(xiàn)的復(fù)雜程度而在功能和性能方面做出必要的權(quán)衡和讓步。另外,進(jìn)度調(diào)度的機(jī)制還要考慮到“公正性”,讓系統(tǒng)所有進(jìn)程都有機(jī)會(huì)向前推進(jìn),盡管其進(jìn)度各有不同,并最終受到CPU速度和負(fù)載的影響。更重要的是,還要防止死鎖的發(fā)生,以及防止對(duì)CPU能力的不合理使用,也就是說(shuō)要防止CPU尚有能力且有進(jìn)程等執(zhí)行,卻由于某種原因而長(zhǎng)時(shí)間得不到執(zhí)行的情況。一旦這些情況發(fā)生,調(diào)度機(jī)制還能識(shí)別與化解。調(diào)度器必須選擇最迫切需要運(yùn)行而且可以執(zhí)行的進(jìn)程來(lái)執(zhí)行??蛇\(yùn)行進(jìn)程是一個(gè)只等待CPU資源的進(jìn)程。Linux使用基于優(yōu)先級(jí)的簡(jiǎn)單調(diào)度算法來(lái)選擇下一個(gè)運(yùn)行進(jìn)程。當(dāng)選定新進(jìn)程后,系統(tǒng)必須將當(dāng)前進(jìn)程的狀態(tài),處理器中的寄存器以及上下文狀態(tài)保存到task_struct結(jié)構(gòu)中。同時(shí)它將重新設(shè)置新進(jìn)程的狀態(tài)并將系統(tǒng)控制權(quán)交給此進(jìn)程。為了將CPU時(shí)間合理的分配給系統(tǒng)中每個(gè)可執(zhí)行進(jìn)程,調(diào)度管理器必須將這些時(shí)間信息也保存在task_struct中。如果當(dāng)前進(jìn)程的調(diào)度策略是時(shí)間片輪轉(zhuǎn),則它被放回到運(yùn)行隊(duì)列。如果任務(wù)可中斷且從上次被調(diào)度后接收到了一個(gè)信號(hào),則它的狀態(tài)變?yōu)檫\(yùn)行態(tài)。如果當(dāng)前進(jìn)程的狀態(tài)是Running,則狀態(tài)保持不變。那些既不處于Running狀態(tài)又不是可中斷的進(jìn)程將會(huì)從運(yùn)行隊(duì)列中刪除。這意味著調(diào)度管理器選擇運(yùn)行進(jìn)程時(shí)不會(huì)將這些進(jìn)程考慮在內(nèi)。調(diào)度器在運(yùn)行隊(duì)列中選擇一個(gè)最迫切需要運(yùn)行的進(jìn)程。如果運(yùn)行隊(duì)列中存在實(shí)時(shí)進(jìn)程(那些具有實(shí)時(shí)調(diào)度策略的進(jìn)程),則它們比普通進(jìn)程更多的優(yōu)先級(jí)權(quán)值。在存在多個(gè)相同優(yōu)先級(jí)進(jìn)程的平衡系統(tǒng)中,每個(gè)進(jìn)程被依次執(zhí)行,這就是Round

Robin策略。然而由于進(jìn)程經(jīng)常需要等待某些資源,所以它們的運(yùn)行順序也常發(fā)變化。如果系統(tǒng)選擇其他進(jìn)程運(yùn)行,則必須被掛起當(dāng)前進(jìn)程且開(kāi)始執(zhí)行新進(jìn)程。進(jìn)程執(zhí)行時(shí)將使用寄存器、物理內(nèi)存以及CPU。每次調(diào)用子程序時(shí),它將參數(shù)放在寄存器中并把返回地址放置在堆棧中,所以調(diào)度管理器總是運(yùn)行在當(dāng)前進(jìn)程的上下文。進(jìn)程的切換發(fā)生在調(diào)度管理器運(yùn)行之后。以前進(jìn)程保存的上下文與當(dāng)前進(jìn)程加載時(shí)的上下文相同,包括進(jìn)程程序計(jì)數(shù)器和寄存器內(nèi)容。如果以前或者當(dāng)前進(jìn)程使用了虛擬內(nèi)存,則系統(tǒng)必須更新其頁(yè)表入口,這與具體體系結(jié)構(gòu)有關(guān)。如果處理器使用了轉(zhuǎn)換旁視緩沖或者緩沖了頁(yè)表入口(如Alpha

AXP),那么必須沖刷以前運(yùn)行進(jìn)程的頁(yè)表入口。5.2.4存儲(chǔ)管理 在這里所說(shuō)的存儲(chǔ)管理一般指的是內(nèi)存管理,在計(jì)算機(jī)業(yè)界,內(nèi)存這個(gè)名詞被廣泛用來(lái)稱呼RAM(隨機(jī)存取內(nèi)存),計(jì)算機(jī)使用隨機(jī)存取內(nèi)存來(lái)儲(chǔ)存執(zhí)行作業(yè)所須的暫時(shí)指令以及數(shù)據(jù),以使計(jì)算機(jī)的CPU能夠更快速讀取儲(chǔ)存在內(nèi)存的指令及數(shù)據(jù)。

下面介紹Linux存儲(chǔ)器管理幾個(gè)基本概念:存儲(chǔ)管理的任務(wù)

存儲(chǔ)管理是Linux中負(fù)責(zé)管理內(nèi)存的模塊。存儲(chǔ)管理的任務(wù)有以下幾點(diǎn):屏蔽各種硬件的內(nèi)存結(jié)構(gòu),并向上層返回同意的訪問(wèn)界面。Linux支持各種各樣的硬件體系結(jié)構(gòu)。對(duì)每種硬件結(jié)構(gòu),其內(nèi)存的組織形式各不相同。然而,對(duì)于用戶的應(yīng)用程序來(lái)說(shuō),總是希望提供一個(gè)同意的界面以供調(diào)用。這樣,存儲(chǔ)模塊就自然要擔(dān)負(fù)這個(gè)屏蔽和轉(zhuǎn)化的任務(wù)。解決進(jìn)程狀態(tài)下內(nèi)存不足的問(wèn)題,按需調(diào)頁(yè)。隨著硬件的發(fā)展,內(nèi)存的增大,軟件業(yè)相應(yīng)地向著大規(guī)模方向發(fā)展。在一個(gè)多進(jìn)程系統(tǒng)中,所有進(jìn)程所占用的內(nèi)存總和往往會(huì)超過(guò)物理內(nèi)存容量。這樣就需要存儲(chǔ)管理實(shí)現(xiàn)能夠利用副存儲(chǔ)器(比如硬盤(pán))進(jìn)行輔助存儲(chǔ)的功能。存儲(chǔ)管理機(jī)制甚至還能夠處理單個(gè)進(jìn)程所占用內(nèi)存超過(guò)主存大小的情況。阻止進(jìn)程肆意訪問(wèn)其他進(jìn)程的地址空間和內(nèi)核地址空間。由于并發(fā)執(zhí)行的進(jìn)程所在的地址空間都不能沖突,而進(jìn)程太多,物理內(nèi)存空間根本不夠,故需要模擬出一個(gè)更大的虛擬邏輯空間提供給上層應(yīng)用程序,并通過(guò)一個(gè)可靠的機(jī)制建立起邏輯空間到物理空間的映射關(guān)系。為進(jìn)程中通信所需要的共享內(nèi)存提供必要的基礎(chǔ)。對(duì)于上層用戶來(lái)講,共享內(nèi)存和普通內(nèi)存是兩種概念;然而對(duì)于存儲(chǔ)管理系統(tǒng)來(lái)講,這兩者卻都是內(nèi)存中的一部分,所有內(nèi)存空間的任一部分都可被劃為共享內(nèi)存使用。因此,實(shí)現(xiàn)共享內(nèi)存的任務(wù)就需要由存儲(chǔ)管理模塊來(lái)實(shí)現(xiàn)虛擬內(nèi)存 虛擬內(nèi)存是現(xiàn)代操作系統(tǒng)的重要特征。對(duì)于一個(gè)多進(jìn)程的操作系統(tǒng)來(lái)說(shuō),每個(gè)進(jìn)程都要占據(jù)自己唯一的內(nèi)存地址空間。虛擬內(nèi)存的基本原理是將內(nèi)存中一部分近期不需要的內(nèi)容移出到外存上,從而讓出一塊內(nèi)存空間,以供其他需要的內(nèi)存使用。當(dāng)要訪問(wèn)到那些已經(jīng)被調(diào)出到外存的數(shù)據(jù)時(shí),存儲(chǔ)管理要將內(nèi)存中一部分不常被訪問(wèn)的數(shù)據(jù)調(diào)出,讓出一塊空間以供需要的數(shù)據(jù)調(diào)入內(nèi)存。頁(yè)面模式

頁(yè)面為存儲(chǔ)管理中調(diào)入調(diào)出的基本單位。在存儲(chǔ)管理中,將內(nèi)存劃分為長(zhǎng)度相等的頁(yè)面。Linux將每個(gè)用戶進(jìn)程4GB長(zhǎng)度的虛擬內(nèi)存劃分成固定大小的頁(yè)面。其中,0~3GB是用戶態(tài)空間,由各進(jìn)程獨(dú)占;3~4GB是內(nèi)核態(tài)空間,由所有進(jìn)程共享,但只有內(nèi)核態(tài)的進(jìn)程才能訪問(wèn)。按需調(diào)頁(yè)

當(dāng)進(jìn)程訪問(wèn)到某個(gè)虛存地址,卻發(fā)現(xiàn)該地址所對(duì)應(yīng)的物理頁(yè)面已經(jīng)被換出內(nèi)存時(shí),系統(tǒng)會(huì)自動(dòng)產(chǎn)生一個(gè)硬件中斷,即缺頁(yè)中斷。在中斷產(chǎn)生后,系統(tǒng)會(huì)自動(dòng)調(diào)用相應(yīng)的中斷處理程序,來(lái)將所需的頁(yè)面從外存調(diào)入,或者干脆新建一個(gè)空白頁(yè)面。這個(gè)過(guò)程就叫做按需調(diào)頁(yè)。對(duì)換

對(duì)于虛擬內(nèi)存頁(yè)面來(lái)說(shuō),總是要將其改動(dòng)過(guò)的內(nèi)容寫(xiě)回到外存中,才能夠?qū)⑵鋪G棄。一個(gè)被更改過(guò)的內(nèi)存頁(yè)面,但還沒(méi)有將其內(nèi)容寫(xiě)到外存中,就稱之為“臟頁(yè)面”。在換入頁(yè)面時(shí),首先考慮的肯定是將“干凈的”頁(yè)面直接丟棄,然后將外存數(shù)據(jù)寫(xiě)進(jìn)來(lái),因?yàn)檫@樣不會(huì)破壞數(shù)據(jù)的完整性。然而這是一個(gè)矛盾,內(nèi)存調(diào)用者希望盡可能少地進(jìn)行外存的刷新,這個(gè)結(jié)果造成內(nèi)存中“臟頁(yè)面”不斷增加,而換入程序又希望盡可能多一些“干凈”頁(yè)面,以便使它們可以很方便地將數(shù)據(jù)調(diào)入。于是,收拾垃圾的工作就由一個(gè)被稱作“對(duì)換”(swap)的程序來(lái)完成。Linux中存儲(chǔ)器管理的相關(guān)概念及實(shí)現(xiàn)

伙伴算法

Linux的伙伴算法把所有的空閑頁(yè)面分為10個(gè)塊組,每組中塊的大小是2的冪次方個(gè)頁(yè)面。工作原理: 如果要求要求分配一個(gè)大小為M個(gè)頁(yè)面的塊,伙伴算法會(huì)先到與要求分配的M個(gè)頁(yè)面大小最接近的空閑塊鏈表中查找,看是否有這樣的一個(gè)空閑塊。如果有,就直接分配;如果沒(méi)有,該算法就會(huì)到下一個(gè)更大的空閑塊鏈表中查找一個(gè)空閑塊,如果有,就將該空閑塊分為兩等份,一份分配出去,另一份就掛入下一級(jí)的空閑塊鏈表中;如果沒(méi)有,就繼續(xù)向更大的空閑塊鏈表中查找,直到查找完所有更大的空閑塊鏈表都沒(méi)找到空閑塊為止(空閑塊鏈表最大為512個(gè)頁(yè)面),如果沒(méi)有的就放棄分配,并發(fā)出出錯(cuò)信息。 以上過(guò)程的逆過(guò)程就是塊的釋放過(guò)程,這也是該算法名字的來(lái)由。滿足以下條件的兩個(gè)塊稱為伙伴:

(1)兩個(gè)塊的大小相同;

(2)兩個(gè)塊的物理地址連續(xù)。slab

Slab是Linux操作系統(tǒng)的一種內(nèi)存分配機(jī)制。Slab中引入了對(duì)象這個(gè)概念,所謂對(duì)象就是存放一組數(shù)據(jù)結(jié)構(gòu)的內(nèi)存區(qū),其方法就是構(gòu)造或析構(gòu)函數(shù),構(gòu)造函數(shù)用于初始化數(shù)據(jù)結(jié)構(gòu)所在的內(nèi)存區(qū),而析構(gòu)函數(shù)收回相應(yīng)的內(nèi)存區(qū)。 實(shí)際上,Linux中對(duì)Slab分配模式有所改進(jìn),它對(duì)內(nèi)存區(qū)的處理并不需要進(jìn)行初始化或回收。出于效率的考慮,Linux并不調(diào)用對(duì)象的構(gòu)造或析構(gòu)函數(shù),而是把指向這兩個(gè)函數(shù)的指針都置為空。Linux中引入slab的豐要目的是為了減少對(duì)伙伴算法的調(diào)用次數(shù)。 緩沖區(qū)就是主存中的一片區(qū)域,把這片區(qū)域劃分為多個(gè)塊,每塊就是一個(gè)Slab,每個(gè)Slab由一個(gè)或多個(gè)頁(yè)面組成,每個(gè)Slab中存放的就是對(duì)象。 對(duì)于小對(duì)象,就把slab的描述結(jié)構(gòu)slab_t放在該slab中;對(duì)于大對(duì)象,則把slab結(jié)構(gòu)游離出來(lái),集中存放。關(guān)于slab中的著色區(qū)再給予具體描述。緩沖區(qū) 每個(gè)緩沖區(qū)還有一個(gè)輪轉(zhuǎn)鎖(spinlock),在對(duì)鏈表進(jìn)行修改時(shí)用這個(gè)輪轉(zhuǎn)鎖進(jìn)行同步。 緩沖區(qū)只有在一下兩個(gè)條件都成立的的時(shí)候才能分配到Slab: (1)已發(fā)出—個(gè)分配新對(duì)象的請(qǐng)求; (2)緩沖區(qū)不包含任何空閑對(duì)象。 在內(nèi)核中當(dāng)初始化開(kāi)銷不大的數(shù)據(jù)結(jié)構(gòu)可以合用一個(gè)通用的緩沖區(qū)。地址映射機(jī)制

顧名思義地址映射就是建立幾種存儲(chǔ)媒介(內(nèi)存,輔存,虛存)間的關(guān)聯(lián),完成地址間的相互轉(zhuǎn)換,它既包括磁盤(pán)文件到虛擬內(nèi)存的映射,也包括虛擬內(nèi)存到物理內(nèi)存的映射。進(jìn)程的虛擬空間

堆棧區(qū)位于進(jìn)程虛擬空間的頂部,運(yùn)行時(shí)由頂向下延伸。數(shù)據(jù)和代碼段位于虛擬空間的底部,運(yùn)行時(shí)不向上延伸。中間的空洞是進(jìn)程在運(yùn)行時(shí)可以動(dòng)態(tài)分配的空間(也叫動(dòng)態(tài)內(nèi)存)。頁(yè)故障的產(chǎn)生(1)一是程序出現(xiàn)錯(cuò)誤(2)另一種情況是,虛擬地址有效,但其所對(duì)應(yīng)的也當(dāng)前不在物理內(nèi)存中,即缺頁(yè)錯(cuò)誤(3)最后一種情況是,要訪問(wèn)的虛擬地址被寫(xiě)保護(hù),即保護(hù)錯(cuò)誤

交換機(jī)制 當(dāng)物理內(nèi)存出現(xiàn)不足時(shí),Linux內(nèi)存管理子系統(tǒng)需要釋放部分物理內(nèi)存頁(yè)面。這一任務(wù)由內(nèi)核的交換守護(hù)進(jìn)程kswapd完成,該內(nèi)核守護(hù)進(jìn)程實(shí)際是一個(gè)內(nèi)核線程,它在內(nèi)核初始化時(shí)啟動(dòng),并周期地運(yùn)行。它的任務(wù)就是保證系統(tǒng)中具有足夠的空閑頁(yè)面,從而使內(nèi)存管理子系統(tǒng)能夠有效運(yùn)行。頁(yè)面交換策略:

策略一:需要時(shí)才交換 策略二:系統(tǒng)空閑時(shí)交換 策略三:換出但不立即釋放 策略四:把頁(yè)面換出推遲到不能再推遲為止Linux中新頁(yè)框的分配方案 請(qǐng)求調(diào)頁(yè)(demandpaging):是在類UNIX操作系統(tǒng)中使用較為普遍的一種動(dòng)態(tài)內(nèi)存分配技術(shù)。所謂動(dòng)態(tài)內(nèi)存分配技術(shù)就是指進(jìn)程運(yùn)行所需要的頁(yè)框不是一開(kāi)始就全部分配給進(jìn)程,而是當(dāng)內(nèi)核執(zhí)行進(jìn)程的一個(gè)指令所需的頁(yè)面不在內(nèi)存時(shí),再由CPU的控制單元引起一個(gè)缺頁(yè)異常,這時(shí)再由異常處理程序調(diào)入內(nèi)存。 寫(xiě)時(shí)拷貝(copy_on_write):把一個(gè)頁(yè)面標(biāo)記為只讀,而把代表它的VMA標(biāo)記為可寫(xiě)。因此任何對(duì)頁(yè)面的寫(xiě)操作都會(huì)造成頁(yè)面寫(xiě)訪問(wèn)異常,同樣會(huì)引起缺頁(yè)中斷。緩沖區(qū)高速緩存 緩沖區(qū)高速緩存由設(shè)備標(biāo)識(shí)號(hào)和塊標(biāo)號(hào)索引,因此可以快速找出數(shù)據(jù)塊。 緩沖區(qū)高速緩存的大小可以變化。當(dāng)需要新緩沖區(qū)而現(xiàn)在又沒(méi)有可用的緩沖區(qū)時(shí),就按需分配頁(yè)面。刷新機(jī)制 采取的解決辦法是為計(jì)算機(jī)裝備一個(gè)不需要經(jīng)過(guò)頁(yè)表就能把虛擬地址映射成物理地址的小的硬件設(shè)備,這個(gè)設(shè)備叫做TLB(翻譯后援存儲(chǔ)器,TranslationLooksideBuffer),有時(shí)也叫做相聯(lián)存儲(chǔ)器(AssociativeMemov),它通常在MMU內(nèi)部,條目的數(shù)量較少。

每一個(gè)TLB寄存器的每個(gè)條目包含一個(gè)頁(yè)面的信息:有效位、虛頁(yè)面號(hào)、修改位、保護(hù)碼和頁(yè)面所在的物理頁(yè)面號(hào),它們和頁(yè)面表中的表項(xiàng)一一對(duì)應(yīng)。 在Linux中刷新機(jī)制(包括TLB的刷新和緩存的刷新)主要完成以下兩項(xiàng)工作: (1)保證在任何時(shí)刻內(nèi)存管理硬件所看到的進(jìn)程的內(nèi)核映射與內(nèi)核頁(yè)表一致。 (2)如果負(fù)責(zé)內(nèi)存管理的內(nèi)核代碼對(duì)用戶進(jìn)程頁(yè)進(jìn)行了修改,那么用戶進(jìn)程在被允許繼續(xù)執(zhí)行前必須在緩存中看到正確的數(shù)據(jù)。5.2.5文件系統(tǒng)

文件系統(tǒng)是對(duì)一個(gè)存儲(chǔ)設(shè)備上的數(shù)據(jù)和元數(shù)據(jù)進(jìn)行組織的機(jī)制,Linux文件系統(tǒng)接口為分層的體系結(jié)構(gòu),從而將用戶接口層、文件系統(tǒng)實(shí)現(xiàn)和操作存儲(chǔ)設(shè)備的驅(qū)動(dòng)程序分隔開(kāi)。Linux操作系統(tǒng)下的文件系統(tǒng)結(jié)構(gòu)虛擬文件系統(tǒng)

VFS是物理文件系統(tǒng)與服務(wù)之間的一個(gè)接口層,對(duì)用戶程序隱去各種不同文件系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié),為用戶程序提供一個(gè)統(tǒng)一、抽象、虛擬的文件系統(tǒng)界面。

VFS的功能包括:記錄可用的文件系統(tǒng)的類型;將設(shè)備同對(duì)應(yīng)的文件系統(tǒng)聯(lián)系起來(lái);處理一些面向文件的通用操作。嵌入式文件系統(tǒng)存儲(chǔ)

Linux啟動(dòng)時(shí),第一個(gè)必須掛載的是根文件系統(tǒng),若系統(tǒng)不能從指定設(shè)備上掛載根文件系統(tǒng),則系統(tǒng)會(huì)出錯(cuò)而退出啟動(dòng)。啟動(dòng)之后可以自動(dòng)或手動(dòng)掛載其他的文件系統(tǒng)。因此,一個(gè)系統(tǒng)中可以同時(shí)存在不同的文件系統(tǒng)。 不同的文件系統(tǒng)類型有不同的特點(diǎn),因而根據(jù)存儲(chǔ)設(shè)備的硬件特性、系統(tǒng)需求等有不同的應(yīng)用場(chǎng)合。在嵌入式Linux應(yīng)用中,主要的存儲(chǔ)設(shè)備為RAM(DRAM,SDRAM)和ROM(常采用FLASH存儲(chǔ)器),常用的基于存儲(chǔ)設(shè)備的文件系統(tǒng)類型包括:jffs2,yaffs,cramfs,romfs,ramdisk,ramfs/tmpfs等。嵌入式文件系統(tǒng)(1)ext2、ext3文件系統(tǒng)(2)基于FLASH的文件系統(tǒng)

jffs2;yaffs;Cramfs;Romfs……

(3)基于RAM的文件系統(tǒng)Ramdisk;ramfs/tmpfs……(4)網(wǎng)絡(luò)文件系統(tǒng)NFS(Network)文件系統(tǒng)的目錄結(jié)構(gòu)Linux的目錄結(jié)構(gòu)樹(shù)型目錄結(jié)構(gòu)dir1/-------------dir2/----------file12 |---------dir3/--------------- | |-------dir4 |.................................. ....................................根目錄組織/----------------root/ :超級(jí)用戶目錄包括桌面管理等 |------------home/ :用戶目錄包括用戶信息等 |------------bin/ :執(zhí)行目錄可執(zhí)行文件常用命令 |------------sbin/ :執(zhí)行目錄不提供給用戶使用的命令 |------------boot/ :引導(dǎo)目錄引導(dǎo)系統(tǒng)使用的文件 |------------etc/ :配置目錄系統(tǒng)配置時(shí)使用

|------------dev/ :設(shè)備目錄通過(guò)它訪問(wèn)外設(shè)|------------mnt/:安裝目錄管理員設(shè)備臨時(shí)安裝點(diǎn)|------------opt/ :安裝目錄管理員軟件包放置點(diǎn)|------------lib/ :庫(kù)目錄命令執(zhí)行時(shí)使用|------------usr/ :共享目錄所有用戶的共享文件|------------var/ :數(shù)據(jù)目錄系統(tǒng)運(yùn)行時(shí)要修改數(shù)據(jù)|------------tmp/:數(shù)據(jù)目錄系統(tǒng)運(yùn)行時(shí)要修改數(shù)據(jù)|------------proc/:虛擬目錄文件系統(tǒng)內(nèi)存產(chǎn)生|------------lost+found/:空目錄5.2.6設(shè)備管理 設(shè)備管理是操作系統(tǒng)諸多管理中最復(fù)雜的部分。與Unix系統(tǒng)一樣,Linux系統(tǒng)采用設(shè)備文件統(tǒng)一管理硬件設(shè)備,從而將硬件設(shè)備的特性及管理細(xì)節(jié)對(duì)用戶隱藏起來(lái),實(shí)現(xiàn)用戶程序與設(shè)備無(wú)關(guān)性。設(shè)備分類按設(shè)備的所屬關(guān)系可以將I/O設(shè)備分為以下兩類:(1)系統(tǒng)設(shè)備(2)用戶設(shè)備按設(shè)備的信息交換的單位可將I/O設(shè)備分為以下兩類:(1)字符設(shè)備(2)塊設(shè)備按設(shè)備的共享屬性可將I/O設(shè)備分為以下三類:(1)獨(dú)占設(shè)備(2)共享設(shè)備(3)虛擬設(shè)備根據(jù)設(shè)備的用途,可以把設(shè)備分為存儲(chǔ)設(shè)備與輸入/輸出設(shè)備兩大類。設(shè)備管理的任務(wù)(1)選擇和分配I/O設(shè)備以便進(jìn)行數(shù)據(jù)傳輸操作。(2)控制I/O設(shè)備和CPU(或內(nèi)存)之間交換數(shù)據(jù)。(3)為用戶提供一個(gè)友好的透明接口,把用戶和設(shè)備硬件特性分開(kāi),使得用戶在編制應(yīng)用程序時(shí)不必涉及具體設(shè)備,由系統(tǒng)按用戶的要求來(lái)對(duì)設(shè)備的工作進(jìn)行控制。另外,這個(gè)接口還為新增加的用戶設(shè)備提供一個(gè)和系統(tǒng)核心相連接的入口,以便用戶開(kāi)發(fā)新的設(shè)備管理程序。(4)提高設(shè)備和設(shè)備之間、CPU和設(shè)備之間以及進(jìn)程和進(jìn)程之間的并行操作程度,以使操作系統(tǒng)獲得最佳效率。設(shè)備管理程序一般要提供的功能:(1)提供和進(jìn)程管理系統(tǒng)的接口(2)進(jìn)行設(shè)備分配(3)實(shí)現(xiàn)設(shè)備和設(shè)備、設(shè)備和CPU等之間的并行操作(4)進(jìn)行緩沖管理(5)設(shè)備控制與驅(qū)動(dòng)設(shè)備控制器 設(shè)備控制器是CPU與I/O設(shè)備之間的接口,它接收從CPU發(fā)來(lái)的命令并去控制I/O設(shè)備工作。

大多數(shù)設(shè)備控制器都由以下三部分組成。 (1)設(shè)備控制器與處理機(jī)的接口 (2)設(shè)備控制器與設(shè)備的接口 (3)I/O邏輯I/O通道 設(shè)置I/O通道的目的是使一些原來(lái)由CPU處理的I/O任務(wù)轉(zhuǎn)由通道來(lái)承擔(dān),從而把CPU從繁雜的I/O任務(wù)中解脫出來(lái)。 通道有兩種基本類型:選擇通道和多路通道。 選擇通道又稱高速通道,在物理上它可以連接多個(gè)設(shè)備,但是這些設(shè)備不能同時(shí)工作,在某一段時(shí)間內(nèi)通道只能選擇一個(gè)設(shè)備進(jìn)行工作。

多路通道又分為數(shù)組多路通道和字節(jié)多路通道。 數(shù)組多路通道的基本思想是指,當(dāng)某設(shè)備進(jìn)行數(shù)據(jù)傳送時(shí),通道只為該設(shè)備服務(wù);當(dāng)設(shè)備在執(zhí)行尋址等控制性動(dòng)作時(shí),通道暫時(shí)斷開(kāi)與這個(gè)設(shè)備的連接,掛起該設(shè)備的通道程序,去為其他設(shè)備服務(wù),即執(zhí)行其他設(shè)備的通道程序。 字節(jié)多路通道主要用于連接大量的低速設(shè)備,因此通道在傳送兩個(gè)字節(jié)之間有很多空閑時(shí)間,字節(jié)多路通道正是利用這個(gè)空閑時(shí)間為其他設(shè)備服務(wù)。Linux的I/O控制

Linux的I/O控制方式常用的有三種:查詢等待方式、中斷方式和DMA(內(nèi)存直接存取)方式。(1)查詢等待方式 查詢等待方式又稱輪詢方式(pollingmode)。對(duì)于不支持中斷方式的機(jī)器只能采用這種方式來(lái)控制I/O過(guò)程,所以Linux中也配備了查詢等待方式。(2)中斷方式 在硬件支持中斷的情況下,驅(qū)動(dòng)程序可以使用中斷方式控制I/O過(guò)程。對(duì)I/O過(guò)程控制使用的中斷是硬件中斷,當(dāng)某個(gè)設(shè)備需要服務(wù)時(shí)就向CPU發(fā)出一個(gè)中斷脈沖信號(hào),CPU接收到信號(hào)后根據(jù)中斷請(qǐng)求號(hào)IRQ啟動(dòng)中斷服務(wù)例程。(3)DMA方式 內(nèi)存直接存取技術(shù)是指數(shù)據(jù)在內(nèi)存與I/O設(shè)備間自己接進(jìn)行成塊傳輸。DMA有兩個(gè)技術(shù)特征:首先是直接傳送,其次是塊傳送。 所謂直接傳送,即在內(nèi)存與I/O設(shè)備間傳送一個(gè)數(shù)據(jù)庫(kù)的過(guò)程中,不需要CPU的任何中間干涉,只需要CPU在過(guò)程開(kāi)始時(shí)向設(shè)備發(fā)出“傳送塊數(shù)據(jù)”的命令,然后通過(guò)中斷來(lái)得知過(guò)程是否結(jié)束和下次操作是否就緒。 一個(gè)完整的DMA過(guò)程包括初始化、DMA請(qǐng)求、DMA響應(yīng)、DMA傳輸、DMA結(jié)束5個(gè)階段。(4)通道方式也是一種I/O控制方式,但是這種方式是利用一個(gè)獨(dú)立于CPU以外的、專門管理I/O的處理機(jī)來(lái)控制輸入和輸出,它控制設(shè)備與內(nèi)存直接進(jìn)行數(shù)據(jù)交換,有著自己的通道指令,這些通道指令由CPU啟動(dòng),并在結(jié)束時(shí)向CPU發(fā)出中斷信號(hào)。設(shè)備驅(qū)動(dòng)設(shè)備驅(qū)動(dòng)程序的處理過(guò)程:(1)將抽象要求轉(zhuǎn)換為具體要求(2)檢查I/O請(qǐng)求的合法性(3)讀出和檢查設(shè)備的狀態(tài)(4)傳送必要的參數(shù)(5)工作方式的設(shè)置(6)啟動(dòng)I/O設(shè)備Linux設(shè)備管理的設(shè)備 在Linux系統(tǒng)中,硬件設(shè)備分為兩種,即塊設(shè)備和字符設(shè)備。1)特別文件 用戶是通過(guò)文件系統(tǒng)與設(shè)備接口的,所有設(shè)備都作為特別文件,從而在管理上就具有一些共性。設(shè)備驅(qū)動(dòng)的分層結(jié)構(gòu)

對(duì)于一般文件(即磁盤(pán)文件),要進(jìn)行空間的映射:從普通文件的邏輯空間映射到設(shè)備的邏輯空間,然后在設(shè)備驅(qū)動(dòng)層做進(jìn)一步映射:從設(shè)備的邏輯空間映射到物理空間(即設(shè)備的物理地址空間),進(jìn)而驅(qū)動(dòng)底層物理設(shè)備工作。 對(duì)于設(shè)備文件,則文件的邏輯空間通常就等價(jià)于設(shè)備的邏輯空間,然后從設(shè)備的邏輯空間映射到設(shè)備的物理空間,再驅(qū)動(dòng)底層的物理設(shè)備工作。2)設(shè)備驅(qū)動(dòng)程序和內(nèi)核之間的接口

Linux系統(tǒng)和設(shè)備驅(qū)動(dòng)程序之間使用標(biāo)準(zhǔn)的交互接口。無(wú)論是字符設(shè)備、塊設(shè)備還是網(wǎng)絡(luò)設(shè)備的驅(qū)動(dòng)程序,當(dāng)內(nèi)核請(qǐng)求它們提供服務(wù)時(shí),都使用同樣的接口。 在應(yīng)用程序界面上,利用內(nèi)核提供的系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)可安裝模塊的動(dòng)態(tài)安裝和拆卸。但通常情況下,用戶是利用系統(tǒng)提供的插入模塊工具和移走模塊工具來(lái)裝卸可安裝模塊。插入模塊的工作主要如下: (1)打開(kāi)要安裝的模塊,把它讀到用戶空間。這種“模塊”就是經(jīng)過(guò)編譯但尚未連接的.o文件。 (2)必須把模塊內(nèi)涉及對(duì)外訪問(wèn)的符號(hào)(函數(shù)名或變量名)連接到內(nèi)核,即把這些符號(hào)在內(nèi)核映像中的地址填入該模塊需要訪問(wèn)這些符號(hào)的指令及數(shù)據(jù)結(jié)構(gòu)中。 (3)在內(nèi)核創(chuàng)建一個(gè)module數(shù)據(jù)結(jié)構(gòu),并申請(qǐng)所需的系統(tǒng)空間。 (4)最后,把用戶空間中完成了連接的模塊映像裝入內(nèi)核空間,并在內(nèi)核中“登記”本模塊的有關(guān)數(shù)據(jù)結(jié)構(gòu)(如結(jié)構(gòu)),其中有指向執(zhí)行相關(guān)操作函數(shù)的指針。3)字符設(shè)備 在Linux系統(tǒng)中,打印機(jī)、終端等字符設(shè)備都作為字符特別文件出現(xiàn)在用戶面前。用戶對(duì)字符設(shè)備的使用就和存取普通文件一樣。在應(yīng)用程序中,使用標(biāo)準(zhǔn)的系統(tǒng)調(diào)用來(lái)打開(kāi)、關(guān)閉、讀寫(xiě)字符設(shè)備。當(dāng)字符設(shè)備初始化時(shí),其設(shè)備驅(qū)動(dòng)程序被添加到由device_struct結(jié)構(gòu)組成的chrdevs結(jié)構(gòu)數(shù)組中。

device_struct結(jié)構(gòu)由兩項(xiàng)構(gòu)成,一個(gè)是指向已登記的設(shè)備驅(qū)動(dòng)程序名的指針,另一個(gè)是指向結(jié)構(gòu)的指針。而結(jié)構(gòu)的成分幾乎全是函數(shù)指針,分別指向?qū)崿F(xiàn)文件操作的入口函數(shù)。設(shè)備的主設(shè)備號(hào)用來(lái)對(duì)chrdevs數(shù)組進(jìn)行索引。4)塊設(shè)備 對(duì)塊設(shè)備的存取和對(duì)文件的存取方式一樣,其實(shí)現(xiàn)機(jī)制也和字符設(shè)備使用的機(jī)制相同。Linux系統(tǒng)中有一個(gè)名為blkdevs的結(jié)構(gòu)數(shù)組,它描述了一系列在系統(tǒng)中登記的塊設(shè)備。 數(shù)組blkdevs也使用設(shè)備的主設(shè)備號(hào)作為索引,其元素類型是device_struct結(jié)構(gòu)。該結(jié)構(gòu)中包括指向已登記的設(shè)備驅(qū)動(dòng)程序名的指針和指向block_device_operations結(jié)構(gòu)的指針。Linux字符設(shè)備的驅(qū)動(dòng) 主要通過(guò)介紹字符設(shè)備scull(SimpleCharacterUtilityforLoadingLocalities,區(qū)域裝載的簡(jiǎn)單字符工具)的驅(qū)動(dòng)程序編寫(xiě),來(lái)學(xué)習(xí)Linux設(shè)備驅(qū)動(dòng)的基本知識(shí)。scull可以為真正的設(shè)備驅(qū)動(dòng)程序提供樣板。

1)主設(shè)備號(hào)和次設(shè)備號(hào)

2)一些重要的數(shù)據(jù)結(jié)構(gòu)

3)字符設(shè)備的注冊(cè)

4)scull模型的內(nèi)存使用

5)open和release 6)read和write 7)對(duì)于scull設(shè)備有時(shí)需要用到scullpipe設(shè)備,scullpipe設(shè)備是針對(duì)一片內(nèi)存,實(shí)現(xiàn)了一個(gè)circularbuffer(循環(huán)緩沖)5.2.7嵌入式Linux引導(dǎo)過(guò)程 在嵌入式系統(tǒng)中,首先要考慮的就是啟動(dòng)問(wèn)題,即系統(tǒng)如何告知CPU啟動(dòng)位置以及啟動(dòng)方法。一般來(lái)說(shuō),嵌入式系統(tǒng)會(huì)提供多種啟動(dòng)方法。具備FlashROM的系統(tǒng)具備有Flash啟動(dòng)的方式,也有直接從RAM中啟動(dòng)的方法。這些啟動(dòng)部分的工作主要由一個(gè)被稱為bootloader的程序完成。

運(yùn)行Linux的目標(biāo)機(jī)在重新啟動(dòng)后要經(jīng)過(guò)幾個(gè)步驟才能出現(xiàn)系統(tǒng)提示符。最初的步驟是與微處理器硬件相關(guān)的。內(nèi)核本身包含了微處理器體系結(jié)構(gòu)相關(guān)的初始化代碼,這些代碼首先被執(zhí)行。該初始化代碼為保護(hù)模式的運(yùn)算配置微處理器的寄存器,然后調(diào)用微處理器體系結(jié)構(gòu)無(wú)關(guān)的稱為start_kernel的內(nèi)核開(kāi)始點(diǎn)。此后,內(nèi)核的引導(dǎo)過(guò)程對(duì)于所有微處理器體系結(jié)構(gòu)都是完全相同的。Linux的引導(dǎo)過(guò)程包括下列步驟:

1)處理器重新啟動(dòng)之后,執(zhí)行ROM啟動(dòng)代碼。2)ROM啟動(dòng)代碼初始化CPU、內(nèi)存控制器以及片上設(shè)備,然后配置存儲(chǔ)映射。ROM啟動(dòng)代碼隨后執(zhí)行一個(gè)引導(dǎo)裝載程序bootloader。3)引導(dǎo)裝載程序?qū)inux內(nèi)核從Flash或者TFTP服務(wù)器解壓到RAM中。然后跳到內(nèi)存的第一天指令處執(zhí)行。內(nèi)核首先配置微處理器的寄存器,然后調(diào)用start_kernal,它是體系結(jié)構(gòu)無(wú)關(guān)的開(kāi)始點(diǎn)。4)內(nèi)核初始化告訴緩存和各種硬件設(shè)備。5)內(nèi)核掛裝根文件系統(tǒng)。6)內(nèi)核執(zhí)行init進(jìn)程。7)正在執(zhí)行的init進(jìn)程裝載運(yùn)行時(shí)的共享庫(kù)。8)init讀取其配置文件/etc/inittab并執(zhí)行執(zhí)行腳本。一般而言,init執(zhí)行一個(gè)啟動(dòng)腳本rc.d/rcs,該腳本配置并啟動(dòng)網(wǎng)絡(luò)和其他系統(tǒng)服務(wù)。9)init進(jìn)入運(yùn)行級(jí)別,在該級(jí)別下可以執(zhí)行系統(tǒng)任務(wù)或開(kāi)始登陸進(jìn)程,最后進(jìn)入用戶會(huì)話階段。嵌入式Linux引導(dǎo)過(guò)程中概念簡(jiǎn)介1)bootloader程序bootloader的作用:(1)初始化處理器。(2)初始化必備的硬件。(3)下載系統(tǒng)映像。(4)初始化操作系統(tǒng)并準(zhǔn)備運(yùn)行。2)嵌入式系統(tǒng)內(nèi)核 對(duì)于使用操作系統(tǒng)的嵌入式系統(tǒng)而言,操作系統(tǒng)一般是以內(nèi)核映像的形式下載到目標(biāo)系統(tǒng)中。以Linux為例子,在系統(tǒng)開(kāi)發(fā)完成之后,將整個(gè)操作系統(tǒng)部分做成壓縮或者沒(méi)有壓縮過(guò)的內(nèi)核映像文件,與文件系統(tǒng)一起傳送到目標(biāo)系統(tǒng)中。通過(guò)bootloader指定地址運(yùn)行Linux內(nèi)核,啟動(dòng)嵌入式Linux系統(tǒng);然后再通過(guò)操作系統(tǒng)解開(kāi)文件系統(tǒng),運(yùn)行應(yīng)用程序。 在內(nèi)核中通常必須的部件是進(jìn)程管理、進(jìn)程間通信、內(nèi)存管理部分,其他部件,如文件系統(tǒng)、驅(qū)動(dòng)程序、網(wǎng)絡(luò)協(xié)議等,都可以配置,并以相關(guān)的方式實(shí)現(xiàn)。3)根文件系統(tǒng) 在嵌入式系統(tǒng)中的“硬盤(pán)”概念一般都以ramdisk的方式實(shí)現(xiàn)。因?yàn)镕alsh這樣斷電后還能繼續(xù)保存數(shù)據(jù)的設(shè)備,其價(jià)格相對(duì)昂貴;然而系統(tǒng)中又無(wú)法使用像硬盤(pán)這樣的大型設(shè)備,因此,需要長(zhǎng)久使用的文件系統(tǒng)數(shù)據(jù),尤其是應(yīng)用程序的可執(zhí)行文件、運(yùn)行庫(kù)等,運(yùn)行時(shí)都放在RAM中。常用的方式就是從RAM中劃分出一塊內(nèi)存虛擬成“硬盤(pán)”,對(duì)它的操作與對(duì)永久存儲(chǔ)器操作一樣。在Linux中就存在這樣的設(shè)備,稱為ramdisk,一般使用的設(shè)備文件是/dev/ram0。 當(dāng)然,根文件系統(tǒng)不一定使用ramdisk實(shí)現(xiàn),還可以用NFS方式通過(guò)網(wǎng)絡(luò)安裝根文件系統(tǒng)。這也是在系統(tǒng)內(nèi)核中實(shí)現(xiàn)的。操作系統(tǒng)啟動(dòng)之后直接通過(guò)內(nèi)核中NFS相關(guān)代碼對(duì)處于網(wǎng)絡(luò)上的NFS文件系統(tǒng)進(jìn)行安裝。文件系統(tǒng)啟動(dòng)的方式可以在內(nèi)核代碼中編寫(xiě)或者啟動(dòng)時(shí)通過(guò)參數(shù)指定。4)重定位和下載

生成了目標(biāo)平臺(tái)需要的image文件之后,就可以通過(guò)相應(yīng)的工具與目標(biāo)板上的bootloader程序進(jìn)行通信。可以使用bootloader提供的,或者通用的終端工具與目標(biāo)板相連接。一般在目標(biāo)板上使用串口,通過(guò)主機(jī)終端工具與目標(biāo)板通信。bootloader中提供下載等控制命令,完成嵌入式系統(tǒng)正式在目標(biāo)板上運(yùn)行之前對(duì)目標(biāo)板的控制任務(wù)。bootloader指定image文件下載的位置。在下載結(jié)束之后,使用bootloader提供的運(yùn)行命令,從指定地址開(kāi)始運(yùn)行嵌入式系統(tǒng)軟件。5)Linux內(nèi)核源代碼中的匯編語(yǔ)言代碼 用匯編語(yǔ)言編寫(xiě)核心代碼中的部分代碼出于以下幾個(gè)方面的考慮:操作系統(tǒng)內(nèi)核中的底層程序直接與硬件打交道,需要用到一些專用的指令,而這些指令在C語(yǔ)言中并無(wú)相對(duì)應(yīng)的語(yǔ)言成分。因此,這些底層的操作需要用匯編語(yǔ)言來(lái)編寫(xiě)。CPU中的一些對(duì)寄存器的操作也是一樣,例如要設(shè)置一個(gè)段寄存器時(shí),也只好用匯編語(yǔ)言來(lái)編寫(xiě)。CPU中的一些特殊指定也沒(méi)有相對(duì)應(yīng)的C語(yǔ)言成分,例如關(guān)中斷、開(kāi)中斷等。此外,在同一體系系統(tǒng)的不同CPU芯片中,特別是新開(kāi)發(fā)出來(lái)的芯片中,往往會(huì)增加一些新的指令,對(duì)這些指令的使用也得用匯編語(yǔ)言。用匯編語(yǔ)言編寫(xiě)的程序,在算法和數(shù)據(jù)結(jié)構(gòu)相同的條件下,常比使用高級(jí)語(yǔ)言編寫(xiě)的效率要高。在在某些特殊的場(chǎng)合,一段程序的空間效率也會(huì)顯得非常重要,這段程序的大小多出一個(gè)字節(jié)也不允許,所以一般使用匯編語(yǔ)言編寫(xiě)。

嵌入式Linux引導(dǎo)過(guò)程一個(gè)最基本的嵌入式Linux系統(tǒng)從軟件的角度可以分為四個(gè)層次:(1)導(dǎo)加載程序bootloader;(2)Linux內(nèi)核;(3)文件系統(tǒng);(4)用戶應(yīng)用程序。嵌入式Linux引導(dǎo)過(guò)程(1)理器重新啟動(dòng)后,首先執(zhí)行啟動(dòng)代碼以初始化內(nèi)存控制器以及片上設(shè)備,然后配置存儲(chǔ)映射。(2)Bootloader把內(nèi)核從Flash等固態(tài)存儲(chǔ)設(shè)備加載到RAM然后跳轉(zhuǎn)到內(nèi)核的第一條指令處執(zhí)行。(3)內(nèi)核首先配置微處理器的寄存器,然后調(diào)用start-kernel它是與微處理器體系結(jié)構(gòu)無(wú)關(guān)的開(kāi)始點(diǎn)。(4)內(nèi)核初始化高速緩存和各種硬件設(shè)備。(5)內(nèi)核掛裝根文件系統(tǒng)。(6)內(nèi)核執(zhí)行init進(jìn)程。(7)init運(yùn)行時(shí)共享庫(kù)。(8)init讀取其配置文件。(9)init最后進(jìn)入用戶會(huì)話階段。在此過(guò)程中bootloader的作用是非常重要的。嵌入式系統(tǒng)中bootloader的作用1)初始化處理器;2)初始化的必備的硬件;3)下載系統(tǒng)映像;4)初始化操作系統(tǒng);5)啟動(dòng)已下載的操作系統(tǒng)。

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論