《Linux操作系統(tǒng)原理與應(yīng)用》課件-第7章_第1頁
《Linux操作系統(tǒng)原理與應(yīng)用》課件-第7章_第2頁
《Linux操作系統(tǒng)原理與應(yīng)用》課件-第7章_第3頁
《Linux操作系統(tǒng)原理與應(yīng)用》課件-第7章_第4頁
《Linux操作系統(tǒng)原理與應(yīng)用》課件-第7章_第5頁
已閱讀5頁,還剩129頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第7章 設(shè)備管理7.1設(shè)備管理概述7.2設(shè)備管理的相關(guān)技術(shù)7.3I/O控制方式7.4設(shè)備的分配與調(diào)度7.5設(shè)備的驅(qū)動7.6Linux設(shè)備管理

7.1 設(shè)備管理概述

7.1.1 設(shè)備管理的功能設(shè)備是系統(tǒng)中的重要資源,無論是應(yīng)用程序還是內(nèi)核本身都要利用設(shè)備來存儲或傳輸數(shù)據(jù)。內(nèi)核中負(fù)責(zé)設(shè)備管理和控制的模塊稱為I/O系統(tǒng)。設(shè)備管理的目標(biāo)有兩個:一是從資源的角度出發(fā),要盡可能地提高設(shè)備的使用效率,提高I/O系統(tǒng)的性能;二是從用戶的角度出發(fā),要屏蔽各種設(shè)備的差異,為應(yīng)用程序使用設(shè)備提供一個統(tǒng)一易用的操作接口。

設(shè)備管理的一個重要原則是要實(shí)現(xiàn)“設(shè)備獨(dú)立性”。設(shè)備獨(dú)立性是指將應(yīng)用程序與具體的設(shè)備獨(dú)立開來,使其不必關(guān)心所用設(shè)備的細(xì)節(jié),也不受底層設(shè)備變化的影響。為此引入了邏輯設(shè)備和物理設(shè)備的概念。

I/O系統(tǒng)的效率問題也是一個很重要的設(shè)計指標(biāo)。

綜合地說,I/O系統(tǒng)主要完成以下功能:

I/O接口:接收用戶進(jìn)程的I/O請求,將請求的邏輯設(shè)備映射到物理設(shè)備。

I/O調(diào)度:根據(jù)設(shè)備的特點(diǎn)對設(shè)備進(jìn)行合理的調(diào)度。

設(shè)備的驅(qū)動:啟動設(shè)備進(jìn)行I/O操作,控制數(shù)據(jù)的傳輸。

設(shè)備的中斷處理:對設(shè)備產(chǎn)生的中斷進(jìn)行處理。

7.1.2 設(shè)備的分類

1. 輸入設(shè)備與輸出設(shè)備

按數(shù)據(jù)傳輸方向的不同,I/O設(shè)備分為輸入設(shè)備、輸出設(shè)備和輸入/輸出設(shè)備3類。輸入設(shè)備用于從外界采集或產(chǎn)生數(shù)據(jù),傳送給系統(tǒng)。如鍵盤、鼠標(biāo)等都是輸入設(shè)備。輸出設(shè)備是從系統(tǒng)獲得數(shù)據(jù),以某種形式向外界表現(xiàn)或傳遞的設(shè)備。如顯示器、打印機(jī)等都是輸出設(shè)備。輸入/輸出設(shè)備則是兼具輸入與輸出數(shù)據(jù)功能的設(shè)備。如磁盤、網(wǎng)卡等都是輸入/輸出設(shè)備。

2. 系統(tǒng)設(shè)備與外部設(shè)備

系統(tǒng)設(shè)備是由系統(tǒng)內(nèi)核管理和使用的設(shè)備,如系統(tǒng)時鐘、系統(tǒng)揚(yáng)聲器、總線接口等。系統(tǒng)設(shè)備之外的設(shè)備都屬于外部設(shè)備。兩者區(qū)別在于系統(tǒng)設(shè)備的驅(qū)動由內(nèi)核本身完成,而外部設(shè)備的驅(qū)動由專門的驅(qū)動程序?qū)崿F(xiàn),以內(nèi)核模塊的方式附加到內(nèi)核中。

3. 字符設(shè)備與塊設(shè)備

按數(shù)據(jù)傳輸單位的不同,設(shè)備分為字符設(shè)備和塊設(shè)備。字符設(shè)備是以字節(jié)為單位組織和傳送數(shù)據(jù)的設(shè)備,如終端設(shè)備(顯示器、鍵盤、鼠標(biāo)等)、打印機(jī)、串口設(shè)備等。塊設(shè)備是以數(shù)據(jù)塊為單位組織和傳送數(shù)據(jù)的設(shè)備,如磁盤、光盤、閃存等。

4. 獨(dú)占設(shè)備與共享設(shè)備

按設(shè)備的使用方式,設(shè)備分為獨(dú)占設(shè)備和共享設(shè)備。獨(dú)占設(shè)備是在某一時間段內(nèi)只能被一個進(jìn)程所使用的設(shè)備。打印機(jī)、終端設(shè)備等都是獨(dú)占設(shè)備。當(dāng)一個進(jìn)程占用打印機(jī)時,其他要打印的進(jìn)程只能等待。共享設(shè)備是允許多個進(jìn)程同時使用的設(shè)備。磁盤等存儲設(shè)備都是共享設(shè)備,它們允許多個進(jìn)程同時訪問,同時存取數(shù)據(jù)。

7.1.3 設(shè)備與系統(tǒng)的接口

計算機(jī)的I/O設(shè)備通常由物理設(shè)備和電子部件兩部分組成。物理設(shè)備是以某種物理方式(機(jī)械、電磁、光電、壓電等)運(yùn)作,實(shí)際執(zhí)行數(shù)據(jù)I/O操作的物理裝置;電子部件是以數(shù)字方式操作的硬件,用于與計算機(jī)接口,控制物理設(shè)備的I/O操作。

一個物理設(shè)備是無法直接與CPU相連接的,這是因?yàn)閮烧咧g存在著以下差異:

(1)控制方式不同:CPU產(chǎn)生的是數(shù)字化命令,而設(shè)備需要某種物理信號來控制。

(2)傳輸方式不同:CPU以字節(jié)為單位傳輸數(shù)據(jù),而設(shè)備可能是以位為單位傳輸?shù)摹?/p>

(3)速度不匹配:設(shè)備的工作速度通常要比CPU慢許多。

(4)時序不一致:設(shè)備有自己的定時控制電路,難以與CPU的時鐘取得一致。

(5)信息形式不同:CPU表達(dá)信息的形式是數(shù)字的,設(shè)備則可能是模擬的。

1. 設(shè)備控制器

在許多情況下,I/O設(shè)備的電子部件與物理設(shè)備是分離的。電子部件稱為設(shè)備控制器,物理設(shè)備就簡稱為設(shè)備。例如:顯卡是顯示控制器,顯示器是由顯卡控制的設(shè)備;聲卡是音頻控制器,音箱或耳機(jī)是音頻設(shè)備。

設(shè)備控制器的復(fù)雜性因設(shè)備而異,相差很大。典型的控制器結(jié)構(gòu)如圖7-1所示。圖7-1設(shè)備控制器的典型結(jié)構(gòu)

各部件的構(gòu)造和功能如下:

1)I/O端口

I/O端口由一組寄存器組成。

2)緩沖區(qū)

塊設(shè)備和流量大的字符設(shè)備(如音頻設(shè)備、視頻設(shè)備等)的控制器中通常還配有緩沖區(qū),用于存放批量傳輸?shù)臄?shù)據(jù)。

3)設(shè)備控制邏輯

設(shè)備控制邏輯是I/O端口與設(shè)備之間的翻譯器,它的主要功能包括:

(1)命令譯碼:設(shè)備控制邏輯負(fù)責(zé)對控制寄存器中的I/O命令進(jìn)行譯碼,確定具體的設(shè)備,產(chǎn)生對設(shè)備的控制信號,控制設(shè)備的操作。

(2)狀態(tài)解釋:當(dāng)設(shè)備執(zhí)行完一個操作后,設(shè)備控制邏輯對從設(shè)備接收到的狀態(tài)信號進(jìn)行解釋和編碼,存入狀態(tài)寄存器。

(3)信息格式轉(zhuǎn)換:設(shè)備控制邏輯需要完成I/O端口與設(shè)備之間的數(shù)據(jù)轉(zhuǎn)換,主要是串行/并行的轉(zhuǎn)換,以及數(shù)/模或模/數(shù)轉(zhuǎn)換等。

(4)傳輸控制:設(shè)備控制邏輯負(fù)責(zé)控制I/O端口或緩沖區(qū)與設(shè)備之間的數(shù)據(jù)傳輸,以及I/O端口或緩沖區(qū)與CPU之間的數(shù)據(jù)傳輸。

4)中斷與DMA控制

大部分的設(shè)備都工作在中斷方式下,它們具有中斷控制邏輯,通過系統(tǒng)的控制總線與中斷系統(tǒng)連接,向中斷控制器發(fā)送中斷請求信號并接收中斷應(yīng)答信號。啟用了DMA方式的控制器還具有DMA控制邏輯,可以向DMA控制器發(fā)送DMA請求和接收DMA應(yīng)答。

5)設(shè)備接口

這是控制器與設(shè)備之間的接口。一個控制器可以帶多個接口,每個接口連接一臺設(shè)備。設(shè)備接口主要負(fù)責(zé)針對具體設(shè)備的信號發(fā)送以及數(shù)據(jù)和狀態(tài)采集等操作。

2. I/O接口

出于通用性設(shè)計的考慮,計算機(jī)硬件結(jié)構(gòu)都提供了一些標(biāo)準(zhǔn)的設(shè)備接口,這些接口遵照統(tǒng)一的標(biāo)準(zhǔn)來設(shè)計,使任何遵從標(biāo)準(zhǔn)設(shè)計的設(shè)備都可通過該接口來與系統(tǒng)連接。根據(jù)所接駁的設(shè)備種類的不同,可以將I/O接口分為兩類:一類是可連接各種類型的設(shè)備的通用接口,如串口、并口、USB接口等都屬于通用I/O接口;另一類是為連接某類設(shè)備而設(shè)置的專用接口,如IDE、SATA和SCSI接口都是塊存儲設(shè)備的專用接口,鍵盤、鼠標(biāo)與顯示器的接口也是專用接口。

通過I/O接口連接設(shè)備的方式可以看作是將設(shè)備控制器的功能分散實(shí)現(xiàn)了:I/O接口實(shí)現(xiàn)與CPU直接連接部分的功能,包括I/O端口、緩沖區(qū)、中斷及DMA控制等,而與設(shè)備直接相關(guān)的控制邏輯則由設(shè)備自行實(shí)現(xiàn)。

標(biāo)準(zhǔn)的I/O接口為設(shè)備的開發(fā)和使用提供了方便,設(shè)備部分只需實(shí)現(xiàn)必要的設(shè)備控制功能即可。這種自己帶有一定控制功能的設(shè)備稱為“智能”(intelligent)設(shè)備。許多串口設(shè)備、USB設(shè)備等都是具有某種程度的智能的設(shè)備。從這個觀點(diǎn)出發(fā),I/O接口可以看作是簡化了的設(shè)備控制器,而設(shè)備則可看作是“智能化”了的設(shè)備。習(xí)慣上我們經(jīng)常稱一些專用的I/O接口為控制器,如SATA控制器、SCSI控制器等,而稱那些通用的I/O接口就是某某接口了。

3. 設(shè)備與系統(tǒng)的連接

歸納起來,設(shè)備與系統(tǒng)的連接方式主要有兩種:一種是集成的設(shè)備控制器+“笨”(dumb)設(shè)備,如內(nèi)置聲卡+音箱;另一種是I/O接口+“智能”設(shè)備,如USB接口+USB音箱(或USB接口+外置聲卡+音箱)。為敘述上的方便,我們把這些方式都看作是一種,就是設(shè)備控制器+設(shè)備。

4. I/O設(shè)備的資源

I/O設(shè)備必須首先獲得一些系統(tǒng)資源才能與系統(tǒng)進(jìn)行交互。I/O設(shè)備的資源占有者是控制器。資源包括如下幾種:

(1)I/O端口地址:控制器中的每個I/O端口寄存器都有一個唯一的地址。一個控制器所擁有的I/O端口地址的總和稱為該設(shè)備的I/O范圍。

(2)中斷申請?zhí)朓RQ:設(shè)備申請中斷使用的中斷線號碼。

(3)緩沖區(qū)地址:控制器中的緩沖區(qū)所映射的內(nèi)存地址范圍。

(4)DMA通道號:設(shè)備申請DMA使用的DMA通道號碼。

7.1.4 I/O系統(tǒng)的硬件結(jié)構(gòu)

不同規(guī)模的計算機(jī)系統(tǒng)的I/O體系結(jié)構(gòu)有較大的差異。大致可以分為主機(jī)I/O系統(tǒng)和PC機(jī)I/O系統(tǒng)。主機(jī)系統(tǒng)的設(shè)備較多,對傳輸速度的要求也高,因而采用具有通道的I/O系統(tǒng)結(jié)構(gòu)。PC機(jī)的I/O系統(tǒng)結(jié)構(gòu)則比較簡單,采用的是總線結(jié)構(gòu),如圖7-2所示。圖7-2?PC機(jī)的I/O體系結(jié)構(gòu)

總線體系結(jié)構(gòu)的特點(diǎn)是以總線為紐帶,將CPU、內(nèi)存和I/O設(shè)備連接在一起。各部件之間的所有信號都要通過總線來傳輸。按傳輸內(nèi)容劃分,總線包括地址總線、數(shù)據(jù)總線和控制總線3部分。地址總線用于傳送數(shù)據(jù)的地址;數(shù)據(jù)總線用于傳送數(shù)據(jù);控制總線包含一些信號線,用來控制時序和系統(tǒng)中的其他控制信號,如中斷請求、DMA請求信號等。

在總線結(jié)構(gòu)的系統(tǒng)中,數(shù)據(jù)的交換路線主要有以下兩種:

(1)CPU與慢速的字符設(shè)備交換數(shù)據(jù)時,由CPU控制設(shè)備與內(nèi)存之間的數(shù)據(jù)交換。輸入時,CPU從控制器中將數(shù)據(jù)讀到CPU的內(nèi)部寄存器中,再寫到內(nèi)存單元中;輸出時則相反,將內(nèi)存數(shù)據(jù)讀到CPU的寄存器中,再寫到控制器的數(shù)據(jù)寄存器中。

(2)CPU與高速的塊設(shè)備交換數(shù)據(jù)時,以DMA方式進(jìn)行。DMA控制器先申請總線使用權(quán),然后控制設(shè)備直接與內(nèi)存?zhèn)鬏敂?shù)據(jù)。

7.1.5 I/O系統(tǒng)的軟件結(jié)構(gòu)

I/O系統(tǒng)硬件需要在I/O系統(tǒng)軟件的管理和驅(qū)動下工作。I/O系統(tǒng)的軟件大多采用分層結(jié)構(gòu)設(shè)計。分層結(jié)構(gòu)的底層是設(shè)備相關(guān)部分,由各個設(shè)備的驅(qū)動程序組成。上層軟件是設(shè)備無關(guān)部分,包括I/O系統(tǒng)接口和I/O執(zhí)行系統(tǒng)。上層軟件與用戶層接口,接收和處理來自用戶進(jìn)程的I/O請求。I/O系統(tǒng)的軟件結(jié)構(gòu)如圖7-3所示。圖7-3?I/O系統(tǒng)的軟件結(jié)構(gòu)

I/O系統(tǒng)各個部分的功能如下:

1. I/O系統(tǒng)接口

I/O系統(tǒng)接口負(fù)責(zé)接收用戶進(jìn)程提交的I/O請求,并將結(jié)果返回給用戶進(jìn)程。為此,接口軟件需實(shí)現(xiàn)以下功能:

(1)設(shè)備的命名:按命名規(guī)則對每個設(shè)備賦予邏輯名和物理名。

(2)設(shè)備的保護(hù):每個設(shè)備都設(shè)定了訪問權(quán)限,收到用戶的I/O請求后需檢查用戶進(jìn)程的權(quán)限,防止設(shè)備被非法使用。

2. I/O執(zhí)行系統(tǒng)

I/O執(zhí)行系統(tǒng)負(fù)責(zé)處理用戶提交的I/O請求,形成對具體設(shè)備的I/O操作,傳給相應(yīng)的設(shè)備驅(qū)動程序,再將執(zhí)行結(jié)果進(jìn)行轉(zhuǎn)換,返回給用戶。這部分主要包括以下功能:

(1)設(shè)備映射:將I/O請求中對邏輯設(shè)備的請求轉(zhuǎn)變?yōu)閷ξ锢碓O(shè)備的請求。

(2)設(shè)備分配:按一定的策略將設(shè)備分配給進(jìn)程使用,使用完畢后回收設(shè)備。

(3)I/O調(diào)度:對I/O操作的順序進(jìn)行優(yōu)化,啟動驅(qū)動程序執(zhí)行I/O操作。

(4)緩沖區(qū)管理:塊設(shè)備的數(shù)據(jù)傳輸采用緩沖方式,傳輸數(shù)據(jù)前,系統(tǒng)需要為塊設(shè)備分配緩沖區(qū),傳輸結(jié)束后,系統(tǒng)還要管理緩沖區(qū),為后續(xù)的I/O操作提供緩存功能。

3. 設(shè)備驅(qū)動層

設(shè)備驅(qū)動層包括了設(shè)備的驅(qū)動程序和中斷處理程序,它們都和具體的設(shè)備相關(guān)。驅(qū)動程序是操作控制器的軟件,它直接和具體的設(shè)備打交道,負(fù)責(zé)設(shè)備的驅(qū)動和控制。中斷處理程序負(fù)責(zé)處理設(shè)備產(chǎn)生的中斷。這部分的主要功能是:

(1)設(shè)備驅(qū)動:根據(jù)上層指令啟動設(shè)備執(zhí)行,并對I/O傳輸過程進(jìn)行控制。

(2)中斷處理:對設(shè)備的操作結(jié)果或異常情況進(jìn)行處理。

7.2 設(shè)備管理的相關(guān)技術(shù)

7.2.1 中斷技術(shù)1. 中斷的概念在計算機(jī)運(yùn)行期間,當(dāng)系統(tǒng)內(nèi)部或外部發(fā)生了某個異步事件需要CPU處理時,CPU將暫時中止當(dāng)前進(jìn)程的執(zhí)行,轉(zhuǎn)去執(zhí)行相應(yīng)的事件處理程序,待處理完畢后又返回被中斷處繼續(xù)執(zhí)行,這個過程就稱為“中斷”(interrupt)。異步事件是指與系統(tǒng)運(yùn)行沒有時序關(guān)系的、不可預(yù)期的事件,如用戶按下鍵盤按鍵,磁盤傳輸數(shù)據(jù)完成,系統(tǒng)硬件出現(xiàn)故障等。

2. 中斷源與中斷分類

引起中斷發(fā)生的事件稱為中斷源。通常中斷源是由硬件產(chǎn)生的信號。例如,當(dāng)敲擊鍵盤時,終端控制器就會產(chǎn)生一個鍵盤中斷信號。也有一些中斷源是來自軟件的,比如進(jìn)程執(zhí)行中的頁故障中斷。總之,中斷源是需要CPU處理的事件。計算機(jī)系統(tǒng)中有很多種中斷源,按其發(fā)生的位置可以分為內(nèi)部中斷和外部中斷兩大類。

內(nèi)部中斷是在CPU執(zhí)行指令的過程中同步發(fā)生的異常事件,如除數(shù)為0、內(nèi)存溢出、頁故障等。這類中斷事件也稱為“異?!保╡xception)。此外,中斷指令也被看作是一種特殊的內(nèi)部中斷,稱為“自陷”(trap)或“軟件中斷”(softwareinterrupt)。

外部中斷是由CPU之外的硬件引發(fā)的異步事件,分為非屏蔽中斷(non-maskableinterrupt)與可屏蔽中斷(maskableinterrupt)兩類。非屏蔽中斷是由硬件故障引起的緊急事件,如電源掉電、奇偶校驗(yàn)錯等。這類中斷危及系統(tǒng)的運(yùn)行,因此一旦發(fā)生必須立即處理??善帘沃袛嘀饕怯稍O(shè)備I/O操作所引發(fā)的中斷,也稱為I/O中斷。

3. 中斷的請求

設(shè)備將產(chǎn)生的中斷信號提交給CPU,請求其進(jìn)行處理,這個提交過程稱為中斷請求。由于I/O設(shè)備的數(shù)量眾多,無法將它們與CPU直接連接來傳遞中斷信號,因此需要一個中間部件作為橋梁,這個部件就是“可編程中斷控制器”(ProgrammableInterruptController,PIC)。所有的I/O中斷信號都匯集到PIC,由它進(jìn)行必要的裁決和轉(zhuǎn)換后再提交給CPU。

4. 中斷的響應(yīng)

CPU在收到中斷信號后暫停執(zhí)行當(dāng)前的進(jìn)程,轉(zhuǎn)入相應(yīng)的中斷處理程序進(jìn)行處理,這個反應(yīng)過程稱為中斷響應(yīng)。CPU在每次執(zhí)行完一條指令后都會檢查有無中斷請求,在有中斷且沒有被屏蔽的情況下CPU會立即予以響應(yīng)。

并不是所有中斷請求都會得到及時的響應(yīng)。對于非屏蔽中斷,一旦發(fā)生則CPU必須無條件響應(yīng);對于可屏蔽中斷,CPU是否予以響應(yīng)取決于CPU中的一個“中斷允許狀態(tài)位”。該狀態(tài)位為0時,CPU將不響應(yīng)中斷,這稱為關(guān)中斷;該狀態(tài)位為1時,則允許CPU響應(yīng)中斷,這稱為開中斷。在多數(shù)情況下CPU處于開中斷狀態(tài)。

中斷響應(yīng)過程的主要動作是:從PIC獲取中斷號,根據(jù)中斷號檢索IDT,得到該中斷對應(yīng)的中斷處理程序入口地址,然后保存當(dāng)前進(jìn)程的斷點(diǎn)信息,轉(zhuǎn)入中斷處理程序入口去執(zhí)行相應(yīng)的中斷處理程序。

5. 中斷的處理

中斷處理程序的執(zhí)行過程大致分為如下幾個階段:

(1)保存現(xiàn)場:中斷響應(yīng)的時間很短,只保存了斷點(diǎn)相關(guān)的幾個寄存器。

(2)處理中斷:中斷的處理方式因設(shè)備和中斷的不同而異。

(3)?恢復(fù)現(xiàn)場返回:中斷處理完成后,將保存現(xiàn)場時保存的寄存器值恢復(fù)到CPU的寄存器中,然后執(zhí)行中斷返回指令,結(jié)束整個中斷過程。

6. 中斷在I/O系統(tǒng)中的應(yīng)用

下面以鼠標(biāo)設(shè)備的中斷處理為例,概括地描述I/O中斷的實(shí)際應(yīng)用。

在安裝鼠標(biāo)的驅(qū)動程序時,它的中斷處理程序也被安裝到內(nèi)核中。鼠標(biāo)驅(qū)動程序負(fù)責(zé)監(jiān)測位置移動和按鍵等事件,鼠標(biāo)的中斷處理程序則負(fù)責(zé)處理這些事件。以鼠標(biāo)移動為例,當(dāng)鼠標(biāo)硬件檢測出一個微小的位移時便會產(chǎn)生一個中斷信號(觸發(fā)中斷的位移量大小取決于鼠標(biāo)的分辨率,分辨率越高則鼠標(biāo)越靈敏),該信號經(jīng)過PIC提交給CPU。CPU響應(yīng)此中斷后便會轉(zhuǎn)入鼠標(biāo)中斷處理程序。

7.2.2 緩沖與緩存技術(shù)

1. 緩沖技術(shù)

緩沖(buffering)技術(shù)就是為了解決設(shè)備和CPU之間處理速度不匹配的問題而引入的。CPU的數(shù)據(jù)傳輸速度可以達(dá)到納秒級,而對于像磁盤這樣的機(jī)電存儲設(shè)備,其數(shù)據(jù)傳輸速度是毫秒級的。

2. 緩存技術(shù)

與緩沖技術(shù)有著細(xì)微差別的另一個技術(shù)是緩存(caching)技術(shù)。緩存區(qū)(cache)是為了臨時存放與設(shè)備交換的數(shù)據(jù)而設(shè)置的數(shù)據(jù)暫存區(qū),通常位于內(nèi)存或設(shè)備控制器的緩存芯片中。

操作系統(tǒng)中廣泛地應(yīng)用了緩存技術(shù),如文件系統(tǒng)中的頁面緩存和目錄項緩存等。內(nèi)存管理中的快表和slab也是一種緩存。此外,應(yīng)用軟件中常用緩存技術(shù)來提高性能,如Web服務(wù)器將經(jīng)常被訪問的網(wǎng)頁保存在緩存中,以提高網(wǎng)絡(luò)訪問速度,減少網(wǎng)絡(luò)流量。

3. 緩沖與緩存的差異

緩沖與緩存的基本原理和作用是相似的,如果不加區(qū)分的話,都可以稱之為緩沖。但兩者之間確實(shí)存在一定的差異:緩沖的作用在于協(xié)調(diào)速度不匹配的I/O傳輸過程,而緩存的作用在于減少對設(shè)備的實(shí)際訪問次數(shù)。這個差異導(dǎo)致了兩者的管理方法有所不同。

4. 緩沖的實(shí)現(xiàn)方式

根據(jù)緩沖區(qū)所在的位置,緩沖可以分為硬緩沖和軟緩沖兩種。硬緩沖就是設(shè)備自帶的緩沖區(qū),位于設(shè)備控制器或設(shè)備上;軟緩沖是在內(nèi)存中開辟的緩沖區(qū)。

1)軟緩沖的實(shí)現(xiàn)方式

軟緩沖是在內(nèi)存中設(shè)置緩沖區(qū),用于暫存數(shù)據(jù)供進(jìn)程快速地獲取或輸出。

根據(jù)設(shè)置的緩沖區(qū)的個數(shù),緩沖區(qū)分為以下幾種:

(1)單緩沖:只設(shè)置一個緩沖區(qū)。

(2)雙緩沖:設(shè)置兩個緩沖區(qū),當(dāng)一個進(jìn)程寫一個緩沖區(qū)時,另一個進(jìn)程可以讀另一個緩沖區(qū),這樣就在一定程度上實(shí)現(xiàn)了讀寫操作的并行性。

(3)環(huán)形緩沖:將多個緩沖區(qū)連接成一個環(huán)形隊列,輸入進(jìn)程沿著環(huán)路順序地寫各個緩沖區(qū),輸出進(jìn)程隨后順序地讀各個緩沖區(qū)。

(4) 緩沖池:設(shè)置一組公用緩沖區(qū),由專門的管理程序統(tǒng)一管理,供多個I/O進(jìn)程共享。進(jìn)程需要時就申請,使用完畢后再釋放。這種管理方法提高了緩沖區(qū)的利用率。

2)硬緩沖的實(shí)現(xiàn)方式

硬緩沖就是在設(shè)備上設(shè)置緩存器,在設(shè)備內(nèi)部存儲和I/O接口之間起到一個緩沖和緩存的作用。以磁盤緩存為例,磁盤上帶有一個存取速度極快的緩存芯片,用于暫存讀寫的數(shù)據(jù)塊。在讀取磁盤時,磁盤控制器會控制磁頭把正在讀取的數(shù)據(jù)塊的下一個或者幾個塊中的數(shù)據(jù)讀到緩存中。

7.2.3 DMA技術(shù)

用中斷方式控制I/O傳送時,每傳送一個字節(jié)就要向CPU發(fā)一次中斷請求,傳輸1?KB數(shù)據(jù)需要發(fā)一千多次中斷請求,這對于塊設(shè)備來說效率太低。為了減少CPU對I/O傳輸過程的干預(yù),PC機(jī)系統(tǒng)采用了DMA機(jī)制,用以控制塊設(shè)備的批量數(shù)據(jù)傳送。

DMA即“直接存儲器訪問”(DirectMemoryAccess),其思想是用一個特殊的設(shè)備控制器來控制塊設(shè)備,使其可以直接與主存交換數(shù)據(jù)。這個控制器就稱為DMA控制器。

在以總線為中心的體系結(jié)構(gòu)中,任何數(shù)據(jù)交換都要通過總線進(jìn)行??偩€控制權(quán)在CPU,也就是說,所有的數(shù)據(jù)交換都需要CPU參與完成,外設(shè)無權(quán)使用總線直接訪問內(nèi)存。DMA控制器的特殊之處在于它能從CPU那里暫時地獲得總線控制權(quán),在沒有CPU的參與下控制外設(shè)與內(nèi)存直接傳送數(shù)據(jù)。直接的意思就是指數(shù)據(jù)傳送不必經(jīng)過CPU的寄存器,直接從設(shè)備寫入內(nèi)存或從內(nèi)存送入設(shè)備。在整個傳輸期間,設(shè)備不產(chǎn)生任何中斷,僅在全部數(shù)據(jù)傳輸完成后才向CPU發(fā)出中斷。

一個完整的DMA傳輸過程需要經(jīng)過以下4個步驟:

1. DMA請求

CPU通過I/O指令來初始化DMA控制器,為它設(shè)定I/O操作的參數(shù)。

2. DMA響應(yīng)

DMA控制器對DMA請求予以判別,然后向CPU發(fā)出總線使用權(quán)的請求。

3. DMA傳輸

DMA控制器獲得總線控制權(quán)后,對設(shè)備控制器發(fā)出讀/寫命令,控制設(shè)備直接與內(nèi)存進(jìn)行數(shù)據(jù)傳輸。

4. DMA結(jié)束

完成規(guī)定的批量數(shù)據(jù)傳送后,DMA控制器即釋放總線控制權(quán),向設(shè)備控制器發(fā)出結(jié)束信號,并向CPU提出DMA中斷請求。

可以看出,在DMA控制器的控制下,設(shè)備能夠直接與內(nèi)存?zhèn)魉团繑?shù)據(jù),僅在傳輸?shù)慕Y(jié)束時才需要中斷CPU。因此,DMA方式大大減少了CPU對I/O控制的干預(yù),提高了CPU與設(shè)備的并行化程度。

7.3 I/O控制方式

I/O控制就是控制數(shù)據(jù)在I/O設(shè)備與CPU、內(nèi)存之間的傳輸,這是設(shè)備管理的一個主要功能。隨著計算機(jī)技術(shù)的發(fā)展,I/O控制方式也在不斷地發(fā)展。從最早的程序I/O方式,發(fā)展到中斷驅(qū)動方式、DMA控制方式和通道方式,數(shù)據(jù)傳輸速率不斷提高。而貫穿整個發(fā)展過程的一條宗旨就是盡量減少CPU對I/O傳輸?shù)母深A(yù),把CPU從繁雜的I/O控制事務(wù)中解脫出來,提高CPU與外設(shè)的并行化程度。

7.3.1 程序I/O方式

在設(shè)備控制器的狀態(tài)寄存器中有一個用于表示設(shè)備工作狀態(tài)的“忙”(busy)標(biāo)志位。該位為1表示設(shè)備忙,為0則表示閑。進(jìn)程通過執(zhí)行I/O測試指令可以檢測這個標(biāo)志位,獲得設(shè)備的當(dāng)前工作狀態(tài)。程序I/O方式就是由執(zhí)行I/O的進(jìn)程直接訪問這個標(biāo)志位來控制設(shè)備的I/O操作。以輸出為例,進(jìn)程準(zhǔn)備好要輸出的數(shù)據(jù),然后通過I/O命令啟動設(shè)備,設(shè)備開始傳輸數(shù)據(jù),并設(shè)置“忙”標(biāo)志。在數(shù)據(jù)傳輸過程中,進(jìn)程循環(huán)地檢測“忙”標(biāo)志位,直到設(shè)備完成了數(shù)據(jù)傳輸,并清除了“忙”標(biāo)志。之后進(jìn)程繼續(xù)執(zhí)行,準(zhǔn)備下一批的輸出數(shù)據(jù)。圖7-4描述了程序I/O方式的操作時序。圖7-4程序I/O方式的操作時序

7.3.2 中斷I/O方式

中斷I/O方式的傳輸過程是:當(dāng)進(jìn)程需要數(shù)據(jù)傳輸時,CPU為其啟動設(shè)備進(jìn)行I/O操作。此后CPU不是被動地測試等待,而是繼續(xù)執(zhí)行原進(jìn)程或其他進(jìn)程。設(shè)備控制器按照I/O命令的要求控制設(shè)備進(jìn)行數(shù)據(jù)傳輸,當(dāng)設(shè)備完成I/O操作后,采用中斷方式向CPU報告。CPU響應(yīng)中斷后,暫時停止當(dāng)前進(jìn)程的執(zhí)行,轉(zhuǎn)去進(jìn)行中斷處理。中斷處理完成后,CPU轉(zhuǎn)到被中斷的進(jìn)程或新調(diào)度的進(jìn)程繼續(xù)執(zhí)行。圖7-5描述了中斷I/O方式的操作時序。圖7-5中斷I/O方式的操作時序

7.3.3 DMA方式

DMA方式的傳輸過程是:當(dāng)需要數(shù)據(jù)傳輸時,CPU向DMA控制器發(fā)送傳輸參數(shù)和啟動命令,啟動DMA操作,然后繼續(xù)執(zhí)行進(jìn)程。與此同時,DMA控制器也開始工作,控制設(shè)備連續(xù)地與內(nèi)存?zhèn)鬏敂?shù)據(jù)。待全部數(shù)據(jù)傳輸完成后,DMA控制器用中斷通知CPU,CPU進(jìn)行相應(yīng)的中斷處理,然后繼續(xù)執(zhí)行進(jìn)程。圖7-6描述了DMA方式的I/O操作時序。圖7-6?DMA方式的I/O操作時序

7.3.4 通道方式

追求高效率的中大型機(jī)多采用具有獨(dú)立處理器的通道來實(shí)現(xiàn)I/O傳輸控制。通道(channel)是一個專門用于控制I/O操作的處理器,它執(zhí)行通道程序,控制外設(shè)與主存之間交換數(shù)據(jù)。通道的工作過程是:CPU生成通道程序,啟動通道執(zhí)行,然后繼續(xù)執(zhí)行進(jìn)程。這段時間中,通道與CPU是完全并行工作的,CPU執(zhí)行進(jìn)程,通道執(zhí)行通道程序,控制設(shè)備與內(nèi)存?zhèn)鬏斠慌鷶?shù)據(jù)。傳輸結(jié)束后,通道產(chǎn)生通道中斷向CPU報告,CPU處理完通道中斷后就可以直接使用內(nèi)存的數(shù)據(jù)了。

7.4 設(shè)備的分配與調(diào)度

7.4.1 設(shè)備分配的方法當(dāng)進(jìn)程提出I/O請求時,I/O系統(tǒng)便按照一定的策略把設(shè)備分配給進(jìn)程使用。設(shè)備分配的原則是要盡可能地滿足進(jìn)程的要求,同時又能充分發(fā)揮設(shè)備的使用效率。

1. 分配策略設(shè)備的分配策略可分為獨(dú)占分配、共享分配和虛擬分配。分配策略取決于設(shè)備的固有屬性。

2. 獨(dú)占設(shè)備的分配算法

當(dāng)有多個進(jìn)程同時請求獨(dú)占設(shè)備時,系統(tǒng)應(yīng)采用某種算法決定將設(shè)備分配給哪個進(jìn)程使用。分配算法通常有先進(jìn)先出法和優(yōu)先級法兩種。

3. 共享設(shè)備的調(diào)度算法

共享設(shè)備的分配采用的是I/O調(diào)度方式。共享設(shè)備主要是磁盤等塊設(shè)備,其特點(diǎn)是允許多個進(jìn)程同時訪問。

7.4.2 虛擬設(shè)備技術(shù)

獨(dú)占設(shè)備在一個期間內(nèi)只能被一個進(jìn)程使用。由于設(shè)備的速度慢,因此其他要使用同一設(shè)備的進(jìn)程不得不長時間地等待。

圖7-7描述SPOOLing系統(tǒng)的工作原理。系統(tǒng)在外存開辟了一個打印機(jī)輸出井和一個磁帶機(jī)輸入井。對用戶進(jìn)程來說,這就是一臺虛擬打印機(jī)和一臺虛擬磁帶機(jī)。當(dāng)進(jìn)程需要從磁帶機(jī)輸入數(shù)據(jù)時,SPOOLing系統(tǒng)就啟動磁帶機(jī),將數(shù)據(jù)讀入磁帶機(jī)輸入井中。隨后進(jìn)程直接從輸入井提取數(shù)據(jù),不需再等待。當(dāng)進(jìn)程需要打印輸出時,它將數(shù)據(jù)高速地送入打印機(jī)輸出井,然后繼續(xù)運(yùn)行。在輸出井等待打印的數(shù)據(jù)形成打印隊列,由SPOOLing系統(tǒng)控制在適當(dāng)?shù)臅r候完成實(shí)際的打印工作。圖7-7?SPOOLing系統(tǒng)工作原理示意圖

7.5 設(shè)備的驅(qū)動

7.5.1 設(shè)備的驅(qū)動方式設(shè)備驅(qū)動程序(devicedriver)是直接管理和操縱設(shè)備控制器的軟件。從圖7-3中可以看出,設(shè)備驅(qū)動程序位于I/O軟件系統(tǒng)的底部,它們接收上層軟件的I/O請求,將其轉(zhuǎn)化為設(shè)備控制器的命令代碼,操縱設(shè)備控制器完成數(shù)據(jù)傳輸?shù)娜^程。驅(qū)動程序是系統(tǒng)中唯一了解設(shè)備操作細(xì)節(jié)的軟件,每個設(shè)備控制器都需要由一個特定的驅(qū)動程序來控制。

設(shè)備驅(qū)動和中斷處理程序都是內(nèi)核代碼,它們運(yùn)行在核心態(tài),可以訪問控制器中的I/O端口、驅(qū)動和處置設(shè)備。它們與設(shè)備控制器之間的交互方式有以下幾種:

(1)發(fā)送I/O命令:驅(qū)動程序?qū)/O操作命令發(fā)送到控制器的命令寄存器中,控制器根據(jù)命令啟動設(shè)備執(zhí)行操作。

(2)傳輸數(shù)據(jù):驅(qū)動程序讀寫控制器中的數(shù)據(jù)寄存器或緩沖區(qū),控制內(nèi)存與控制器之間的數(shù)據(jù)傳輸;控制器則控制設(shè)備完成對外界的數(shù)據(jù)I/O。

(3)查詢設(shè)備狀態(tài):控制器將設(shè)備的狀態(tài)信息存入狀態(tài)寄存器中,供驅(qū)動程序和中斷處理程序查詢。

(4)中斷請求與處理:當(dāng)設(shè)備產(chǎn)生中斷時,控制器向中斷機(jī)構(gòu)發(fā)出中斷請求;中斷處理程序查詢控制器中的狀態(tài)信息,判斷中斷原因并進(jìn)行處理。

7.5.2 驅(qū)動程序與中斷處理程序

1. 設(shè)備驅(qū)動程序

設(shè)備驅(qū)動程序的功能會因設(shè)備不同而有或多或少的差別,但通常應(yīng)包括以下幾個:

(1)設(shè)備的初始化與復(fù)位:在執(zhí)行I/O操作前首先要對設(shè)備進(jìn)行初始化,使其準(zhǔn)備就緒;在設(shè)備操作結(jié)束后應(yīng)將其復(fù)位以備下次使用。

(2)設(shè)備的讀寫操作:進(jìn)程通常使用讀寫操作來請求與設(shè)備傳輸數(shù)據(jù)。

(3)設(shè)備的控制操作:除了讀寫操作外,設(shè)備還可能需要執(zhí)行一些特定的控制操作。

(4)設(shè)備的檢測操作:在需要時,驅(qū)動程序要對設(shè)備進(jìn)行某些常規(guī)或特定的檢測。

2. 設(shè)備中斷處理程序

設(shè)備中斷處理程序的工作是對設(shè)備傳輸?shù)慕Y(jié)果進(jìn)行必要的處理。最簡單的處理就是對設(shè)備進(jìn)行應(yīng)答,通知它中斷已被接收,可以繼續(xù)工作了。復(fù)雜的處理還包括對數(shù)據(jù)進(jìn)行分析和處理,以及對傳輸錯誤進(jìn)行判斷和處理等。

中斷處理程序的編程除了需遵循內(nèi)核編碼規(guī)范外,還需要注意以下要點(diǎn):

(1)中斷處理時會關(guān)閉同一中斷線上的中斷請求,因此它必須盡快地完成工作,不然會造成后續(xù)中斷的丟失。

(2)中斷處理程序不與任何進(jìn)程相關(guān)聯(lián),因此它不允許被阻塞,也不能訪問用戶進(jìn)程的地址空間。這就是說,中斷處理程序不能做任何會引起自己被阻塞的操作,如訪問有競爭的資源等,也不能向用戶進(jìn)程直接傳輸數(shù)據(jù)。

7.6 Linux設(shè)備管理

7.6.1 Linux設(shè)備管理綜述Linux設(shè)備管理的主要特點(diǎn)是把設(shè)備當(dāng)作文件來看待,只要安裝了設(shè)備的驅(qū)動程序,應(yīng)用程序就可以像使用文件一樣使用設(shè)備,而不必知道它們的具體存在形式和操作方式。也就是說,應(yīng)用程序只與文件系統(tǒng)打交道,并不依賴于具體的設(shè)備,這就是設(shè)備獨(dú)立性。

1. Linux設(shè)備的標(biāo)識

在Linux系統(tǒng)中,每個設(shè)備都對應(yīng)一個設(shè)備文件,位于/dev目錄下。設(shè)備文件是一種特殊類型的文件,字符設(shè)備的文件類型為“c”,塊設(shè)備的文件類型為“b”。設(shè)備文件的權(quán)限模式就是對該設(shè)備的訪問權(quán)限。

例7.1用ls命令查看打印機(jī)、終端和硬盤設(shè)備文件的詳細(xì)信息。

2. Linux偽設(shè)備及其標(biāo)識

常用的偽設(shè)備有如下幾種:

空設(shè)備/dev/null:可寫入,無輸出,常用于丟棄不需要的輸出流。

滿設(shè)備/dev/full:寫入時總返回“設(shè)備滿”錯誤,常用于測試I/O程序。

零設(shè)備/dev/zero:輸出0序列,常用于產(chǎn)生一個特定大小的空白文件。

隨機(jī)數(shù)設(shè)備/dev/random:輸出隨機(jī)數(shù),可以用作隨機(jī)數(shù)發(fā)生器。

3. 設(shè)備文件的描述結(jié)構(gòu)

同普通文件一樣,每個設(shè)備文件都有一個獨(dú)立的i節(jié)點(diǎn)。不過設(shè)備文件的i節(jié)點(diǎn)與普通文件的i節(jié)點(diǎn)有所不同,其中包含了主次設(shè)備號和一些設(shè)備描述信息。設(shè)備文件與普通文件的另一個不同之處是它只有i節(jié)點(diǎn),沒有數(shù)據(jù)塊,因?yàn)樗⒉话魏螌?shí)際數(shù)據(jù)。因此,設(shè)備文件也常被稱為“設(shè)備節(jié)點(diǎn)”。

7.6.2 LinuxI/O系統(tǒng)的軟件結(jié)構(gòu)

Linux實(shí)現(xiàn)設(shè)備獨(dú)立性的手段是通過分層軟件結(jié)構(gòu),把設(shè)備納入文件系統(tǒng)的管理之下,使進(jìn)程可以通過文件系統(tǒng)的接口來使用設(shè)備。因此,Linux的I/O系統(tǒng)與文件系統(tǒng)以層次化的結(jié)構(gòu)有機(jī)地結(jié)合在一起,形成了一個文件與設(shè)備共用的結(jié)構(gòu)框架。圖7-8描述了這個框架的結(jié)構(gòu)。圖7-8?Linux文件I/O系統(tǒng)的組成結(jié)構(gòu)

I/O操作方式分為以下兩種:

(1)字符I/O方式:字符設(shè)備文件采用字符I/O方式進(jìn)行訪問。

(2)塊I/O方式:常規(guī)文件和塊設(shè)備文件都采用塊I/O方式進(jìn)行訪問。

7.6.3 Linux的設(shè)備管理機(jī)制

1. 設(shè)備注冊管理

設(shè)備注冊的工作就是在內(nèi)核中為其建立有關(guān)設(shè)備、驅(qū)動和資源的描述結(jié)構(gòu),使其能被內(nèi)核識別和使用。內(nèi)核將登記和保管所有注冊設(shè)備的注冊信息,供相關(guān)進(jìn)程查詢使用。

1)設(shè)備模型

設(shè)備相關(guān)的描述信息構(gòu)成了內(nèi)核中最為繁雜的數(shù)據(jù)結(jié)構(gòu)。

2)sysfs文件系統(tǒng)

為了使用戶進(jìn)程也能獲取內(nèi)核中的設(shè)備信息,Linux將設(shè)備模型的內(nèi)容導(dǎo)出到一個稱為sysfs的文件系統(tǒng)中,掛裝在/sys目錄下。

3)設(shè)備的注冊與注銷

在系統(tǒng)初始化時,內(nèi)核將檢測所有連到系統(tǒng)上的設(shè)備,加載它們的驅(qū)動。系統(tǒng)內(nèi)部設(shè)備的驅(qū)動(如內(nèi)置硬盤、終端等的驅(qū)動)是內(nèi)核自帶的,隨內(nèi)核一起加載;其他設(shè)備的驅(qū)動則以獨(dú)立內(nèi)核模塊的形式加載到內(nèi)核上。

2. 設(shè)備文件管理

1)設(shè)備文件系統(tǒng)

設(shè)備文件是設(shè)備所對應(yīng)的特殊文件,也稱為設(shè)備節(jié)點(diǎn)。所有設(shè)備的設(shè)備節(jié)點(diǎn)都保存在一個稱為devtmpfs的設(shè)備文件系統(tǒng)中。在系統(tǒng)啟動時,devtmpfs被掛裝在/dev目錄下。

2)設(shè)備節(jié)點(diǎn)的建立與刪除

系統(tǒng)啟動時,內(nèi)核首先建立起設(shè)備模型,然后掃描sysfs,識別出其中的每個設(shè)備,由devtmpfs逐一為它們創(chuàng)建設(shè)備節(jié)點(diǎn)。對于系統(tǒng)啟動后出現(xiàn)的熱插拔設(shè)備,內(nèi)核采用動態(tài)方式進(jìn)行處理。當(dāng)檢測到有設(shè)備插入時,內(nèi)核將檢測數(shù)據(jù)與設(shè)備模型中注冊的驅(qū)動進(jìn)行匹配,識別出設(shè)備,然后將其記錄在設(shè)備模型中,再為其生成設(shè)備節(jié)點(diǎn)。設(shè)備拔出的操作與此相反,當(dāng)檢測到有設(shè)備拔出時,內(nèi)核將識別此設(shè)備并讓devtmpfs將它的設(shè)備節(jié)點(diǎn)刪除。

3. 設(shè)備的操作

設(shè)備文件首先要打開才能夠進(jìn)行讀寫等操作。打開設(shè)備文件和打開普通文件一樣,都是通過open()系統(tǒng)調(diào)用來完成的。打開設(shè)備文件主要包括三個層面上的操作:一是在文件系統(tǒng)層面上,要建立設(shè)備對應(yīng)的VFS對象并將它們與進(jìn)程關(guān)聯(lián)上;二是在設(shè)備驅(qū)動層面上,要對驅(qū)動程序進(jìn)行初始化,建立設(shè)備的描述結(jié)構(gòu)并與VFS對象關(guān)聯(lián)上;三是在設(shè)備層面上,要初始化設(shè)備,激活設(shè)備硬件的中斷和DMA。

7.6.4 字符設(shè)備的管理與驅(qū)動

1. 字符設(shè)備的描述

字符設(shè)備驅(qū)動程序在向內(nèi)核注冊時,首先獲得一個主設(shè)備號,然后生成一個cdev,添加到設(shè)備模型中。因此,每個注冊了的字符設(shè)備都對應(yīng)一個cdev結(jié)構(gòu),如圖7-9所示。圖7-9字符設(shè)備的描述結(jié)構(gòu)

2. 字符設(shè)備文件

字符設(shè)備注冊后,devtmpfs會自動地為其在/dev下創(chuàng)建一個設(shè)備節(jié)點(diǎn)inode。字符設(shè)備的inode是為字符設(shè)備特殊設(shè)置的,與常規(guī)文件的inode有所區(qū)別。其中,i_mode字段中的設(shè)備類型為c;i_rdev為設(shè)備號,它與cdev的設(shè)備號dev相對應(yīng);i_cdev是連接cdev的指針;i_devices是連入inode鏈表的指針。此外,字符設(shè)備的i_fop所裝配的文件操作集是字符設(shè)備的默認(rèn)操作集def_chr_fops,此操作集中只有open()和llseek()兩個函數(shù),其中的open()函數(shù)指向的是字符設(shè)備專用的打開函數(shù)chrdev_open()。

3. 字符設(shè)備的打開

使用字符設(shè)備前要用open()系統(tǒng)調(diào)用打開設(shè)備文件,參數(shù)是文件的路徑名。操作的第一步是由VFS完成文件系統(tǒng)層面的打開操作,即根據(jù)設(shè)備節(jié)點(diǎn)的信息查找或建立文件的dentry、inode、file對象,增加file對象的引用計數(shù)file.f_count,將其與當(dāng)前進(jìn)程相連接。這個過程與打開普通文件是一樣的。此時,file對象的文件操作集file.f_op上裝載的是inode.i_fop所帶的def_chr_fops。圖7-10字符設(shè)備文件的描述結(jié)構(gòu)

4. 字符設(shè)備的讀寫與控制

設(shè)備文件打開后,進(jìn)程就可以像讀寫普通文件那樣,使用read()、write()、ioctl()等系統(tǒng)調(diào)用來操作設(shè)備了。通過設(shè)備文件的file對象,這些系統(tǒng)調(diào)用被映射到相應(yīng)的設(shè)備驅(qū)動函數(shù)上,驅(qū)動設(shè)備完成指定的I/O操作。

5. 字符設(shè)備的關(guān)閉

關(guān)閉設(shè)備的過程也與關(guān)閉普通文件的過程類似:首先減少file.f_count;如果file.f_count為0則調(diào)用file.f_op->release(),實(shí)際地關(guān)閉設(shè)備,釋放驅(qū)動程序所占有的資源和file對象;最后釋放設(shè)備文件的fd。

7.6.5 塊設(shè)備的管理與驅(qū)動

與字符設(shè)備相比,塊設(shè)備的管理與驅(qū)動技術(shù)要復(fù)雜得多。這有多個原因:一是塊設(shè)備與字符設(shè)備的使用方法不同。裸的塊設(shè)備通常不能直接使用,而是需要進(jìn)行諸如RAID、分區(qū)、分卷等操作,構(gòu)造出若干個獨(dú)立的分區(qū)或卷來使用。二是塊設(shè)備與字符設(shè)備的操作方式不同。字符設(shè)備是順序訪問的,只需控制一個當(dāng)前位置;塊設(shè)備是隨機(jī)訪問的,訪問的位置可以隨機(jī)變化,因而需要更復(fù)雜的尋址技術(shù)。三是塊設(shè)備與字符設(shè)備的作用不同。作為文件系統(tǒng)的基礎(chǔ)存儲設(shè)備,塊設(shè)備的I/O效率對于系統(tǒng)的整體性能更為重要。

1. 塊設(shè)備的概念與描述

從驅(qū)動程序的角度來看,塊設(shè)備就是含有大量扇區(qū)的實(shí)際的硬件設(shè)備,如磁盤、閃存盤等。驅(qū)動程序懂得如何驅(qū)動它運(yùn)轉(zhuǎn)、尋址和讀寫扇區(qū)。這種被驅(qū)動程序直接操控的塊設(shè)備就是物理塊設(shè)備。然而,物理塊設(shè)備并不能直接被文件系統(tǒng)使用。從文件系統(tǒng)的角度來看,塊設(shè)備是可以存放數(shù)據(jù)塊的邏輯上的存儲設(shè)備,它可以是一個盤、一個分區(qū)或是一個卷。這種被文件系統(tǒng)使用的塊設(shè)備就是邏輯塊設(shè)備。文件系統(tǒng)對邏輯塊設(shè)備的操作請求最終將被塊I/O系統(tǒng)轉(zhuǎn)化為對物理塊設(shè)備的I/O操作。

邏輯塊設(shè)備是在物理塊設(shè)備上構(gòu)造出來的,一個物理塊設(shè)備通常對應(yīng)多個邏輯塊設(shè)備。它們具有相同的主設(shè)備號和不同的次設(shè)備號。

顯然,塊設(shè)備的描述比字符設(shè)備要復(fù)雜得多,不但要描述邏輯塊設(shè)備和物理塊設(shè)備,還要描述它們之間的關(guān)聯(lián)關(guān)系。在Linux中,邏輯塊設(shè)備就稱為塊設(shè)備,用block_device結(jié)構(gòu)描述;物理塊設(shè)備則稱為通用塊設(shè)備,用gendisk結(jié)構(gòu)描述。它們之間的關(guān)聯(lián)關(guān)系用分區(qū)表hd_struct結(jié)構(gòu)描述。

塊設(shè)備驅(qū)動向內(nèi)核注冊時,首先建立起設(shè)備的gendisk,加入到設(shè)備模型中。然后掃描設(shè)備的分區(qū)表,建立hd_struct和各個塊設(shè)備的block_device,再將它們與gendisk連接上。圖7-11描述了gendisk和block_device的描述結(jié)構(gòu)以及它們之間的連接關(guān)系。圖7-11塊設(shè)備的描述結(jié)構(gòu)

2. 塊設(shè)備文件的概念與描述

塊設(shè)備中包含有大量的存儲塊,Linux將其抽象為一個含有全部塊的文件,可以像普通文件那樣訪問,隨意地讀取其中的任意塊。這種特殊文件就是塊設(shè)備文件。訪問塊設(shè)備文件就是直接對塊設(shè)備進(jìn)行讀寫。

1)塊設(shè)備文件系統(tǒng)

用于管理塊設(shè)備文件的文件系統(tǒng)是“塊設(shè)備文件系統(tǒng)”bdev。bdev中容納了系統(tǒng)中的所有塊設(shè)備,將它們當(dāng)作文件進(jìn)行管理,實(shí)現(xiàn)塊設(shè)備的文件訪問操作。與ext4等磁盤文件系統(tǒng)不同,bdev是一個特殊的內(nèi)存文件系統(tǒng),在系統(tǒng)初始化期間由內(nèi)核創(chuàng)建。它只供內(nèi)核使用,用戶不可見,所以被稱為“偽”文件系統(tǒng)。

塊設(shè)備操作的復(fù)雜之處在于塊I/O都要用到緩存,因此需要特定的軟件機(jī)制來管理緩存空間和實(shí)施地址映射。bdev系統(tǒng)的做法是:為每個塊設(shè)備建立一個inode,通過inode中的地址空間與VFS的緩存接口,這樣就可以借用VFS的緩存和映射機(jī)制實(shí)現(xiàn)對塊設(shè)備的操作了。因此,bdev中的每個block_device都配有一個inode,用bdev_inode結(jié)構(gòu)封裝在一起,如圖7-12所示。圖7-12?bdev中塊設(shè)備的inode結(jié)構(gòu)

2)塊設(shè)備文件的緩存操作

文件系統(tǒng)使用頁面緩存(pagecache)來緩存文件內(nèi)容,單位是頁;塊I/O系統(tǒng)使用緩沖區(qū)緩存(buffercache)來緩存磁盤I/O數(shù)據(jù),單位是塊?,F(xiàn)在的內(nèi)核已將緩沖區(qū)緩存并入頁面緩存,也就是將緩存頁面當(dāng)作緩沖塊來使用。假如塊的大小為1?KB,頁面的大小為4?KB,則一個緩存頁中就可容納4個緩沖塊。這種用作緩沖塊的頁稱為“緩沖區(qū)頁”(bufferpage)。

3)塊設(shè)備文件的設(shè)備節(jié)點(diǎn)

每個塊設(shè)備都在/dev目錄下有一個設(shè)備節(jié)點(diǎn),也就是設(shè)備文件的inode。塊設(shè)備文件的inode中包含了一些塊設(shè)備文件專有的特殊設(shè)置,其中,i_mode字段中的設(shè)備類型為b,i_rdev為設(shè)備號,i_fop指向的是塊設(shè)備專用的操作集def_blk_fops。

注意塊設(shè)備文件的inode與塊設(shè)備文件系統(tǒng)中的inode是不同的。前者是在/dev下的devtmpfs系統(tǒng)中,它與VFS接口,為用戶提供文件訪問功能;后者是在bdev系統(tǒng)中,是專為塊I/O系統(tǒng)的內(nèi)部實(shí)現(xiàn)而設(shè)置的,用戶不可見。兩個inode都是在塊設(shè)備注冊時建立的,它們通過相同的設(shè)備號i_rdev相匹配,在打開設(shè)備文件時連接在一起。圖7-13是打開后的塊設(shè)備文件的inode描述結(jié)構(gòu),圖中左側(cè)是devtmpfs系統(tǒng)中的inode,右側(cè)是bdev系統(tǒng)中的inode。為區(qū)分起見,我們稱bdev中的inode為內(nèi)部inode。圖7-13塊設(shè)備文件的描述結(jié)構(gòu)

4)塊設(shè)備文件的打開

打開塊設(shè)備文件的過程與打開字符設(shè)備文件類似:首先是建立file、dentry、inode對象,將file對象的引用計數(shù)增1,并將其與進(jìn)程相連接。此時file對象的文件操作集file.f_op上裝配的是def_blk_fops。接著執(zhí)行file.f_op->open(),也就是blkdev_open(),執(zhí)行塊設(shè)備的打開操作。blkdev_open()的主要操作是建立inode與block_device之間的連接,并將自己鏈入block_device的inode鏈表中,如圖7-13所示。注意此時設(shè)備文件的inode.i_mapping指向的不是自帶的緩存地址空間,而是內(nèi)部inode的地址空間。

隨后,inode.i_mapping被賦給file,使file.f_mapping也指向內(nèi)部inode的地址空間,這樣就將對塊設(shè)備文件的操作導(dǎo)向?qū)K設(shè)備的操作了。最后,通過block_device得到gendisk,調(diào)用gendisk.fops->open(),執(zhí)行通用塊設(shè)備的打開操作。

7.6.6 塊I/O系統(tǒng)的實(shí)現(xiàn)策略

如前所述,當(dāng)文件系統(tǒng)需要實(shí)際讀寫塊設(shè)備時,就會調(diào)用readpage()、writepage()等函數(shù),發(fā)起一次實(shí)際的I/O操作。塊設(shè)備的I/O操作由塊I/O子系統(tǒng)負(fù)責(zé)完成。塊I/O子系統(tǒng)由通用塊層、I/O調(diào)度層和設(shè)備驅(qū)動層組成,它們將I/O操作請求逐層處理直到底層設(shè)備。

1. 通用塊層

塊I/O子系統(tǒng)的最上層是通用塊層(genericblocklayer),它的作用是為VFS提供一個通用的塊設(shè)備接口。當(dāng)文件系統(tǒng)需要讀寫塊設(shè)備時,需按通用塊層的標(biāo)準(zhǔn)對I/O操作請求進(jìn)行描述和封裝,再提交給下層處理。

將文件讀寫操作轉(zhuǎn)化為bio需要經(jīng)過幾個步驟:首先是緩存定位,就是將文件空間的讀寫地址映射為頁面緩存的頁地址。這是通過地址空間的Xarray實(shí)現(xiàn)的,屬于緩存層的功能。然后是塊地址映射,就是將緩存空間頁地址轉(zhuǎn)換為塊號,再映射為塊設(shè)備空間的塊號,這是由實(shí)際文件系統(tǒng)的映射機(jī)制完成的,屬于映射層的功能。最后是對塊號進(jìn)行聚合劃分處理,生成bio。這是通用塊層的功能。圖7-14示意了文件操作請求到bio的轉(zhuǎn)化方式。圖7-14塊I/O請求的構(gòu)成示意圖

2. I/O調(diào)度層

磁盤尋址是計算機(jī)中最慢的操作之一。如果直接按上層提交的順序來讀寫磁盤,磁頭就會來回移動,造成整體I/O性能低下。因此,為了優(yōu)化尋址操作,I/O系統(tǒng)既不會簡單地按收到請求的次序提交給磁盤設(shè)備,也不會立即提交。相反,它會在提交前先執(zhí)行合并與排序的預(yù)操作,對I/O操作序列進(jìn)行優(yōu)化,以便降低磁盤尋址時間,提高磁盤I/O性能。這個工作是由I/O調(diào)度層(I/Oschedulerlayer)來完成的。

I/O調(diào)度層的核心是I/O調(diào)度程序,它的功能是接收通用塊層提交的塊I/O請求bio,根據(jù)各個bio的目標(biāo)設(shè)備和扇區(qū)地址對bio進(jìn)行分類組合,形成針對具體塊設(shè)備的操作請求,然后以最優(yōu)的順序派發(fā)給設(shè)備驅(qū)動去執(zhí)行操作。實(shí)現(xiàn)I/O調(diào)度功能的要點(diǎn)是:設(shè)置請求隊列來保存請求,實(shí)施調(diào)度算法來排序請求,選擇調(diào)度時機(jī)來派發(fā)請求。

1)塊設(shè)備的請求隊列

I/O調(diào)度層用到的設(shè)備是通用塊設(shè)備gendisk,每個設(shè)備都設(shè)有一個自己的請求隊列。在打開通用塊設(shè)備時,內(nèi)核為其建立起請求隊列,掛接在gendisk的queue指針上。

I/O請求用request對象描述,其中包含了一組順序的bio,還有請求標(biāo)志、請求狀態(tài)、傳送的扇區(qū)號、命令等信息。請求隊列是一個雙向鏈表,其中的每個節(jié)點(diǎn)都是一個對設(shè)備的I/O請求。請求隊列用request_queue對象來描述,主要內(nèi)容是隊頭指針queue_head、I/O調(diào)度算法指針elevator以及I/O請求處理函數(shù)指針request_fn。I/O調(diào)度算法用elevator_queue對象描述,主要包含了調(diào)度算法類型以及該調(diào)度算法的各種操作,如判斷、合并、插入、取出請求等。I/O請求處理函數(shù)是塊設(shè)備驅(qū)動所提供的用于處理I/O請求的操作函數(shù),也稱為策略函數(shù)。圖7-15是請求隊列的結(jié)構(gòu)描述。圖7-15塊設(shè)備的請求隊列描述

2)I/O調(diào)度算法

最知名的I/O調(diào)度算法是“Linus電梯算法”,即采用類似電梯的工作方式,將磁頭運(yùn)動同方向上的相鄰的請求組織在一起執(zhí)行。當(dāng)有新的請求要加入隊列時,調(diào)度程序首先檢查新請求是否可以合并到隊列中。

Linux內(nèi)核實(shí)現(xiàn)了如下4種I/O調(diào)度程序,可以由驅(qū)動程序選擇使用。

(1)最終期限法(Deadline):Deadline調(diào)度法是對電梯算法的改進(jìn)。

(2)預(yù)測法(Anticipatory):Anticipatory在Deadline的基礎(chǔ)上增加了預(yù)測啟發(fā)能力,將預(yù)計出現(xiàn)的請求與現(xiàn)有請求合并處理,從而優(yōu)化了I/O響應(yīng)時間,同時也能提供良好的系統(tǒng)吞吐量。

(3)完全公平排隊法(CompletelyFairQueuing,CFQ):其特點(diǎn)是按進(jìn)程來劃分和處理I/O請求。

(4)空操作法(Noop):實(shí)際上是沒有調(diào)度。

3)I/O請求的派發(fā)與處理

I/O請求進(jìn)入請求隊列后并不會立即被處理,而是會有適當(dāng)?shù)难舆t。延遲處理有利于把相鄰塊的請求進(jìn)行集中,這就如同電梯在運(yùn)行前進(jìn)行短暫停留以等待更多的乘客一樣。當(dāng)請求隊列中有了一定數(shù)目的請求時,或延遲了一定的時間段后,I/O調(diào)度程序?qū)⒂|發(fā)設(shè)備驅(qū)動程序?qū)φ埱筮M(jìn)行處理。設(shè)備驅(qū)動注冊在request_fn的策略函數(shù)將逐個處理請求隊列中的各個請求,直到隊空為止。在處理一個請求時,策略函數(shù)根據(jù)request中的信息生成控制器操作命令,啟動DMA,控制設(shè)備將數(shù)據(jù)從設(shè)備讀到緩存,或從緩存寫入設(shè)備。

3. 文件的塊I/O操作

如前所述,除了直接I/O方式外,常規(guī)文件和塊設(shè)備文件都是通過緩存讀寫的。文件的地址空間address_space管理著文件在緩存中的所有頁,并負(fù)責(zé)實(shí)施緩存與設(shè)備之間的塊I/O操作。不過,常規(guī)文件與塊設(shè)備文件的地址空間的設(shè)置不同,I/O操作也就有所不同。

1)常規(guī)文件的I/O操作

常規(guī)文件的讀寫操作是由文件系統(tǒng)負(fù)責(zé)實(shí)施的。文件系統(tǒng)在掛裝時要對其所在的塊設(shè)備執(zhí)行打開操作。打開塊設(shè)備的過程是:根據(jù)塊設(shè)備文件的路徑名(如/dev/sda1)在devtmpfs系統(tǒng)中找到它的inode,得到設(shè)備號i_rdev;根據(jù)i_rdev在bdev系統(tǒng)里找到與其匹配的內(nèi)部inode,進(jìn)而得到對應(yīng)的block_device;通過block_device找到所屬的gendisk;調(diào)用gendisk.fops->open(),執(zhí)行通用塊設(shè)備的打開操作。至此設(shè)備已就緒,接下來是生成文件系統(tǒng)的VFS超級塊super_block,將block_device填入其中,然后執(zhí)行VFS層面的掛裝操作。掛裝完成后,文件的I/O操作環(huán)境就搭建好了。

2)塊設(shè)備文件的I/O操作

塊設(shè)備文件打開后就可以訪問了。訪問塊設(shè)備文件與訪問普通文件的區(qū)別體現(xiàn)在file對象的設(shè)置上。普通文件的file.f_op上裝配的是實(shí)際文件系統(tǒng)的操作集,如ext4_file_operations,而塊設(shè)備文件的file.f_op上裝配的是塊設(shè)備專用的def_blk_fops。因此,當(dāng)讀寫塊設(shè)備文件時,實(shí)際執(zhí)行的是塊設(shè)備的讀寫函數(shù)blkdev_read_iter()、blkdev_write_iter()等。讀寫過程也是通過頁面緩存進(jìn)行的。不過,塊設(shè)備文件沒有自己的緩存地址空間,它使用的是對應(yīng)的bdev中塊設(shè)備inode的地址空間。塊設(shè)備文件的讀寫位置與設(shè)備空間的讀寫位置一致通過塊設(shè)備地址空間的Xarray就可直接定位到要讀寫的頁面和塊了。

7.6.7 Linux的中斷處理

從中斷信號產(chǎn)生到中斷處理完畢需要經(jīng)歷中斷請求、中斷響應(yīng)、中斷處理和中斷返回等幾個步驟。整個過程是由硬件的中斷機(jī)構(gòu)與軟件的中斷系統(tǒng)共同實(shí)施的。其中,中斷處理是軟件操作,而中斷請求、中斷響應(yīng)和中斷返回則涉及硬件層面上的動作。本節(jié)以x86/x64硬件架構(gòu)為例,介紹PC機(jī)上Linux系統(tǒng)的中斷處理流程及實(shí)現(xiàn)原理。

1. x86/x64架構(gòu)的中斷機(jī)制

1)中斷向量與IDT表

x86/x64CPU共支持256種中斷,每種中斷都對應(yīng)一個識別號,稱為中斷向量(interruptvector)。其中,0~31為異常和非屏蔽中斷,32~47為可屏蔽中斷,48~255為軟件中斷。

2)中斷控制器

中斷控制器PIC的作用是對中斷信號進(jìn)行收集、管理、轉(zhuǎn)換和提交。所有可屏蔽外部中斷都必須經(jīng)過PIC提交。PIC是可編程的,也就是可以通過修改內(nèi)部寄存器的值來設(shè)置IRQ號與中斷向量之間的映射關(guān)系,確定優(yōu)先權(quán),禁用或激活中斷線等。

3)中斷響應(yīng)機(jī)制

CPU有兩根外部中斷線,即非屏蔽中斷線NMI和可屏蔽中斷線INTR。非屏蔽中斷經(jīng)NMI直接傳遞給CPU,無須請求而被直接響應(yīng)??善帘沃袛鄤t需要通過APIC,經(jīng)INTR傳遞給CPU。CPU是否響應(yīng)INTR線上的中斷請求取決于eflags寄存器中的IF(Interrupt-enableFlag)位,即中斷響應(yīng)允許位。當(dāng)IF位為0時禁止CPU響應(yīng)INTR線上的中斷請求,當(dāng)IF位為1時則允許CPU響應(yīng)。關(guān)中斷期間發(fā)生的可屏蔽中斷將由APIC暫存。此外,當(dāng)CPU在處理NMI的非屏蔽中斷時不響應(yīng)任何中斷,此間發(fā)生的非屏蔽中斷將由CPU鎖存。

4)中斷請求流程

APIC按設(shè)置的優(yōu)先級監(jiān)視各條IRQ中斷

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論