版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第9章 文件和設(shè)備管理示例,9.1 文件系統(tǒng)的特點(diǎn)與文件類別 9.2 文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)及其關(guān)系 9.3 資源管理和地址映射 9.4 目錄與搜索方法 9.5 文件系統(tǒng)的系統(tǒng)調(diào)用 9.6 UNIX System 的中斷和陷阱總控程序 9.7 緩沖區(qū)管理 9.8 塊設(shè)備驅(qū)動 9.9 字符設(shè)備驅(qū)動 本章小結(jié) 習(xí)題,9.1 文件系統(tǒng)的特點(diǎn)與文件類別 9.1.1 特點(diǎn) 本章通過 UNIX 的文件系統(tǒng)來進(jìn)一步深入了解文件系統(tǒng)與操作系統(tǒng)其他部分的關(guān)系以及文件系統(tǒng)的設(shè)計方法。從用戶的角度看,UNIX文件系統(tǒng)具有如圖9.1所示的樹形層次結(jié)構(gòu): 在圖9.1中,根目錄root之下有dev設(shè)備子目錄,bin實(shí)用程序子
2、目錄,lib庫文件子目錄,etc 基本數(shù)據(jù)和維護(hù)實(shí)用程序子目錄,tmp臨時文件子目錄,usr通用子目錄和include 基本數(shù)據(jù)子目錄等。而 UNIX 子目錄則存放UNIX操作系統(tǒng)核心程序自身。這些子目錄又由各自的子目錄構(gòu)成。,圖9.1 UNIX文件系統(tǒng)的層次結(jié)構(gòu)例,文件系統(tǒng)被組織成樹形結(jié)構(gòu)之后,文件名由路徑名給出。路徑名確定一個文件在文件系統(tǒng)中的位置。一個完整的路徑名由代表根目錄的斜杠開始,到所指定的文件為止。例如在圖9.1中,“/usr/users/shi/b.exe”確定了文件 b.exe在文件系統(tǒng)中的位置。另外,路徑名也可從正在執(zhí)行進(jìn)程的當(dāng)前目錄開始指定,例如,若在圖9.1中的當(dāng)前目錄
3、是zhang 的話,路徑名 a.exe與/usr/users/zhang/a.exe具有相同的效果。 一般來說,UNIX文件系統(tǒng)還具有如下特點(diǎn): UNIX的文件是無結(jié)構(gòu)的字符流式文件。 文件可以動態(tài)地增長或減少。, 文件數(shù)據(jù)可由文件擁有者設(shè)置相應(yīng)的訪問權(quán)限而受到保護(hù)。 外部設(shè)備,例如終端用磁帶、磁盤設(shè)備、鍵盤等都被看作文件。從而,設(shè)備可通過文件系統(tǒng)隱蔽掉設(shè)備特性。在文件系統(tǒng)中,設(shè)備文件占據(jù)著文件系統(tǒng)目錄結(jié)構(gòu)中相應(yīng)的位置,用戶程序按與存取其他文件時所使用的系統(tǒng)調(diào)用和語法來讀、寫設(shè)備文件。因此,用戶程序既沒有必要知道設(shè)備的內(nèi)部特性,也不必在更換或增加設(shè)備之后修改自己。,9.1.2 文件的分類 UN
4、IX文件可分為普通文件、目錄文件和設(shè)備文件。 普通文件即存儲用戶和系統(tǒng)的有關(guān)數(shù)據(jù)和程序的文件。它是無結(jié)構(gòu)、無記錄概念的字符流式文件。 目錄文件則是由文件系統(tǒng)中的各個目錄所形成的文件。這種文件在形式上同普通文件一樣,由系統(tǒng)將其解釋成目錄。在UNIX系統(tǒng)中,一個目錄文件由多個目錄項(xiàng)組成,而每個目錄項(xiàng)則由文件名及指示相應(yīng)的文件說明信息表(i節(jié)點(diǎn)) 的標(biāo)識符id組成。,普通文件和目錄文件都是無結(jié)構(gòu)、無記錄概念的字符流式文件。文件系統(tǒng)以512 字節(jié)為一塊,文件在塊內(nèi)連續(xù)存放。對于普通文件和目錄文件來說,文件的存放方式既可以是順序存取的,也可以是直接存取的。UNIX文件在文件系統(tǒng)中的存放采用的是索引結(jié)構(gòu)方
5、法,從而,對文件存儲塊的分配可以是非連續(xù)的,且文件長度可以動態(tài)變化。 設(shè)備文件與普通文件和目錄文件不同,它除了在目錄文件和文件說明信息表,也就是 i結(jié)點(diǎn)中占據(jù)相應(yīng)的位置之外,并不占有實(shí)際的物理存儲塊。因此,對設(shè)備文件的讀、寫操作將實(shí)際上變?yōu)閷υO(shè)備的操作,而對設(shè)備文件的保護(hù)也將變成對設(shè)備的保護(hù)。例如: cp /dev/tty terminalread 把在終端上敲進(jìn)的字符(設(shè)備文件/dev/tty是用戶終端) 讀入,并把它們復(fù)制到文件 terminalread上。,9.2 文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)及其關(guān)系 9.2.1 文件系統(tǒng)的存儲結(jié)構(gòu) UNIX系統(tǒng)把文件信息存儲在磁盤或磁帶上,不過,UNIX系統(tǒng)的磁
6、盤文件組織也可以當(dāng)作一個連續(xù)的物理塊構(gòu)成的磁帶文件卷看待。在 UNIX 系統(tǒng)中,一個物理存儲器可包含一個或多個文件系統(tǒng)。這些文件系統(tǒng)可以被動態(tài)裝卸。為了簡單起見,假定在一個計算機(jī)系統(tǒng)中只存在一個文件系統(tǒng)。,文件系統(tǒng)由每塊 512字節(jié)或 512字節(jié)的任意倍數(shù)所構(gòu)成的邏輯塊序列組成。在同一個文件系統(tǒng)中,這些邏輯塊的大小完全相同。塊長的選取將直接影響設(shè)備與主存之間的數(shù)據(jù)傳輸速率和內(nèi)存的存儲能力。大的塊長將使得內(nèi)存和設(shè)備之間的數(shù)據(jù)傳輸更加容易,但反過來又使得內(nèi)存頁面長度增加,從而影響內(nèi)存的有效存儲能力。在 UNIX 的許多版本中,大都采用每塊 512字節(jié)。 文件卷的結(jié)構(gòu)如圖9.2所示。其中第 0# 塊
7、是引導(dǎo)塊(boot block)。 引導(dǎo)塊中裝有引導(dǎo)或初啟操作系統(tǒng)的引導(dǎo)代碼。,圖9.2 文件系統(tǒng)存儲結(jié)構(gòu) 顯然,在有多個文件系統(tǒng)的計算機(jī)系統(tǒng)中,只有一個文件系統(tǒng)的引導(dǎo)塊中裝有引導(dǎo)代碼,而其他的引導(dǎo)塊則是空的。 塊是超級塊(superblock)。超級塊用來描述文件系統(tǒng)的狀態(tài),例如文件系統(tǒng)的大小、有關(guān)空閑區(qū)分配和回收用的堆棧等。有關(guān)超級塊的結(jié)構(gòu)將在后面部分進(jìn)一步介紹。,從2塊開始到 K+1# 塊為止的區(qū)域被用來存放文件說明信息,也就是 BFD表。UNIX系統(tǒng)把一個文件的說明信息稱為 i節(jié)點(diǎn)或索引節(jié)點(diǎn)(inode list)。索引節(jié)點(diǎn)表的大小由系統(tǒng)管理人員在進(jìn)行系統(tǒng)配置時指定。 K+2# 以后的
8、塊稱為數(shù)據(jù)塊,其中存放文件數(shù)據(jù),包括目錄文件數(shù)據(jù)。UNIX系統(tǒng)中文件系統(tǒng)的任一數(shù)據(jù)塊只能屬于文件系統(tǒng)中某一個文件或空閑。,9.2.2 幾種常用的數(shù)據(jù)結(jié)構(gòu) 1.資源管理結(jié)構(gòu) filsys 超級塊中存放的最重要的數(shù)據(jù)結(jié)構(gòu)是資源管理結(jié)構(gòu) filsys。該結(jié)構(gòu)中含有文件系統(tǒng)空閑塊分配用堆棧及 i節(jié)點(diǎn)分配用數(shù)據(jù)結(jié)構(gòu)。在塊設(shè)備作為文件卷安裝時,結(jié)構(gòu)filsys 的內(nèi)容被復(fù)制到內(nèi)存專用區(qū)中,以使得對空閑塊和 i節(jié)點(diǎn)的分配與回收能在內(nèi)存進(jìn)行。當(dāng)文件卷被卸下或需要重新讀入或?qū)懗鲇嘘P(guān)堆棧的內(nèi)容時,則將內(nèi)存中的 filsys 結(jié)構(gòu)復(fù)制回超級塊中。 UNIX System 中的 filsys 結(jié)構(gòu)如下:,struct
9、 filsys 文件卷總塊數(shù); i 節(jié)點(diǎn)表塊數(shù); 空閑塊棧區(qū)(小于或等于50); 空閑塊棧指針; 空閑塊棧互斥標(biāo)志; 空閑塊總數(shù); 空閑 i節(jié)點(diǎn)數(shù)組指針; 空閑磁盤 i節(jié)點(diǎn)指針; 空閑 i節(jié)點(diǎn)數(shù)組互斥標(biāo)志; 空閑 i節(jié)點(diǎn)總數(shù); filsys 的修改標(biāo)志,等; filsys 結(jié)構(gòu)被用來進(jìn)行文件空閑塊和 i節(jié)點(diǎn)項(xiàng)的分配與回收。,2. i節(jié)點(diǎn) UNIX文件系統(tǒng)采用 SFD和 BFD方式管理文件。其中 SFD稱為符號文件目錄,存放文件名以及指示該文件的文件說明信息表標(biāo)識符id。由文件名和指示文件說明信息表的標(biāo)識符id稱為目錄,把存放文件說明信息和相應(yīng)標(biāo)識符的 BFD稱為 i節(jié)點(diǎn)。 i節(jié)點(diǎn)又分為磁盤 i
10、節(jié)點(diǎn)和內(nèi)存活動 i節(jié)點(diǎn)。其中磁盤 i節(jié)點(diǎn)以靜態(tài)形式存放文件說明信息。磁盤 i節(jié)點(diǎn) dinode 結(jié)構(gòu)包括:,struct dinode 文件模式; 與該 i節(jié)點(diǎn)聯(lián)接的文件數(shù); 用戶標(biāo)識; 文件大小; 存取權(quán)限; 同組用戶標(biāo)識; 該文件所用物理塊的塊號; 文件存取時間、修改時間和建立時間; 其中,文件模式表示文件類型,而用戶標(biāo)識符以及同組用戶標(biāo)識定義對該文件具有存取權(quán)的用戶集合,與該 i節(jié)點(diǎn)聯(lián)接的文件數(shù)表示有多少個不同的文件名指向該文件。另外,該文件所用的物理塊號是一個由 40 個字節(jié)組成的字符數(shù)組 di_addr40,它指明文件數(shù)據(jù)安放在邏輯盤上的位置。,在 UNIX System 中磁盤 i
11、節(jié)點(diǎn)的項(xiàng)占用64個字節(jié)。因此,一個長 512個字節(jié)的塊可存放 8 個 i節(jié)點(diǎn)項(xiàng)。 系統(tǒng)在對文件進(jìn)行各種操作時,為了減少設(shè)備的啟動次數(shù)以及提高操作速度,總是把相應(yīng)的磁盤 i節(jié)點(diǎn)復(fù)制到內(nèi)存的特定區(qū)域內(nèi)存 i節(jié)點(diǎn)表中。 內(nèi)存 i節(jié)點(diǎn)結(jié)構(gòu) inode除了包含磁盤 i節(jié)點(diǎn)結(jié)構(gòu)的各項(xiàng)之外,還包含了當(dāng)前打開文件的狀態(tài)信息。例如,內(nèi)存 i節(jié)點(diǎn)的狀態(tài):包括該節(jié)點(diǎn)是否已被鎖住,是否有進(jìn)程等待訪問該 i節(jié)點(diǎn)等。 總之,與 filsys 用于空閑區(qū)的分配與回收不一樣, i節(jié)點(diǎn)主要用來存放文件的說明信息,以便進(jìn)程利用 i節(jié)點(diǎn)中的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)信息搜索查找文件信息以及完成對文件信息的保護(hù)和共享。,3.目錄項(xiàng) UNIX
12、系統(tǒng)的目錄項(xiàng)由文件名和磁盤 i節(jié)點(diǎn)標(biāo)識符id組成。其中文件名長度占14個字節(jié),標(biāo)識符id占 2個字節(jié)。從而,在一個 512字節(jié)的磁盤塊中可以存放32個目錄項(xiàng)。,4.系統(tǒng)打開文件表和用戶打開文件表 在UNIX系統(tǒng)中,文件系統(tǒng)主要描述程序和數(shù)據(jù)的靜的概念,而進(jìn)程則反應(yīng)這些程序和數(shù)據(jù)的動的特性。進(jìn)程怎樣才能對文件發(fā)生作用呢?從用戶的角度來看,用戶程序可使用對文件系統(tǒng)進(jìn)行操作的系統(tǒng)調(diào)用來完成。但是,從系統(tǒng)內(nèi)部的角度來說,則需要有相應(yīng)的數(shù)據(jù)結(jié)構(gòu)來記錄和控制打開文件的用戶進(jìn)程以及記錄和控制那些共享同一文件的用戶進(jìn)程。為此 UNIX系統(tǒng)設(shè)置了用戶打開文件表和系統(tǒng)打開文件表。 用戶打開文件表一般放在 user
13、 數(shù)據(jù)結(jié)構(gòu)中。使用用戶打開文件表,一個進(jìn)程可同時打開 20 個左右的文件??纱蜷_的文件表項(xiàng) u_ofile中含有打開文件的描述符fd,以及系統(tǒng)打開文件表的入口指針fp等。,系統(tǒng)打開文件表主要用來指明打開同一文件的不同進(jìn)程和不同進(jìn)程所使用的不同打開路徑,以及這些不同進(jìn)程和不同打開路徑所對應(yīng)的讀寫指針。因此可以認(rèn)為系統(tǒng)打開文件表是 i節(jié)點(diǎn)表的補(bǔ)充。系統(tǒng)打開文件表的每一項(xiàng)包括文件標(biāo)識、文件訪問計數(shù)、文件讀寫指針和文件內(nèi)存 i節(jié)點(diǎn)入口指針和訪問標(biāo)志等。其中文件標(biāo)識與用戶打開文件中fp相連;文件訪問計數(shù)指示共享該文件的進(jìn)程數(shù),當(dāng)文件訪問計數(shù)為 0時,則表明已沒有用戶進(jìn)程在使用該文件,從而可以釋放有關(guān)資源
14、。文件讀寫指針則分別指出各進(jìn)程在同一文件中的讀寫位置。 資源管理結(jié)構(gòu)、i節(jié)點(diǎn)以及用戶打開文件表和系統(tǒng)打開文件表的關(guān)系如圖9.3所示:,圖9.3 文件系統(tǒng)中主要數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系,在圖9.3中,用戶進(jìn)程通過用戶打開文件表中的文件描述符fd,找到系統(tǒng)打開文件表的入口地址fp,再由系統(tǒng)打開文件表中對應(yīng)項(xiàng)找到相關(guān) i節(jié)點(diǎn)的入口指針,從而得到操作該文件所需的控制信息。有了 i節(jié)點(diǎn)中的控制信息,文件系統(tǒng)就可對磁盤數(shù)據(jù)區(qū)中的文件進(jìn)行所必需要的操作。另外,在圖9.3中,給出了兩個不同用戶進(jìn)程共享同一文件的例子。這兩個進(jìn)程通過各自不同的文件描述符fdA和fdB,找到系統(tǒng)打開文件表中不同的對應(yīng)項(xiàng),并通過系統(tǒng)打開文
15、件表中的 i節(jié)點(diǎn)指針而找到同一個內(nèi)存i節(jié)點(diǎn),從而完成文件共享。,9.3 資源管理和地址映射 UNIX文件系統(tǒng)的資源管理包括空閑磁盤塊的分配與回收、 i節(jié)點(diǎn)和系統(tǒng)打開文件表的分配與回收等。關(guān)于空閑磁盤塊的分配與回收,UNIX系統(tǒng)采用成組鏈法來管理空閑區(qū)。本節(jié)主要介紹磁盤節(jié)點(diǎn)和內(nèi)存節(jié)點(diǎn)以及系統(tǒng)打開文件表的分配和釋放方法。,9.3.1 磁盤節(jié)點(diǎn)的分配與釋放 當(dāng)一個新文件被建立時,在給該文件分配磁盤存儲區(qū)之前,應(yīng)為該文件分配存放該文件說明信息的磁盤節(jié)點(diǎn)。反之,當(dāng)從文件系統(tǒng)中刪除某個文件時,則要首先刪除它的磁盤節(jié)點(diǎn)項(xiàng)。UNIX System 中的算法 ialloc 被用來為新建立的文件分配磁盤節(jié)點(diǎn)項(xiàng)。文
16、件系統(tǒng)包含一個節(jié)點(diǎn)線性表,且每個磁盤節(jié)點(diǎn)被順序編號。節(jié)點(diǎn)線性表中存放這些被編號的節(jié)點(diǎn)的類型字段。如果一個節(jié)點(diǎn)的類型字段為,則說明這個節(jié)點(diǎn)是空閑的。顯然,當(dāng)一個進(jìn)程需要一個新的節(jié)點(diǎn)時,它可以通過搜索節(jié)點(diǎn)線性表得到它所要得到的節(jié)點(diǎn)項(xiàng)。為改善系統(tǒng)性能,UNIX System 在資源管理結(jié)構(gòu) filsys 中設(shè)置了一個磁盤節(jié)點(diǎn)數(shù)組。該數(shù)組在系統(tǒng)初啟時隨 filsys 結(jié)構(gòu)一起被復(fù)制到內(nèi)存的特定區(qū)中。,算法 ialloc 首先檢查是否有其他進(jìn)程在對磁盤節(jié)點(diǎn)數(shù)組進(jìn)行操作。如果有其他進(jìn)程正在對磁盤節(jié)點(diǎn)數(shù)組進(jìn)行操作,則當(dāng)前進(jìn)程等待直到其他進(jìn)程操作結(jié)束。在沒有其他進(jìn)程對磁盤節(jié)點(diǎn)數(shù)組進(jìn)行操作且磁盤節(jié)點(diǎn)數(shù)組非空時,
17、系統(tǒng)從節(jié)點(diǎn)數(shù)組中分配一個節(jié)點(diǎn)給新創(chuàng)建的文件,然后,修改節(jié)點(diǎn)數(shù)組指針。緊接著,ialloc調(diào)用內(nèi)存節(jié)點(diǎn)分配算法為新建立的文件分配內(nèi)存節(jié)點(diǎn)后將內(nèi)存節(jié)點(diǎn)初始化。在對內(nèi)存節(jié)點(diǎn)進(jìn)行了初始化之后,再將內(nèi)存節(jié)點(diǎn)的內(nèi)容寫回到磁盤節(jié)點(diǎn)中并修改磁盤空閑節(jié)點(diǎn)的計數(shù)。 有關(guān) ialloc 算法,還有幾個問題需要說明,首先是節(jié)點(diǎn)數(shù)組中的節(jié)點(diǎn)號排列方法。系統(tǒng)從磁盤把節(jié)點(diǎn)按從小到大的順序讀進(jìn)i節(jié)點(diǎn)數(shù)組,如圖9.4:,圖9.4 空閑節(jié)點(diǎn)數(shù)組,系統(tǒng)在為進(jìn)程分配磁盤節(jié)點(diǎn)時,按節(jié)點(diǎn)序號從小到大的原則分配。當(dāng)空閑節(jié)點(diǎn)數(shù)組為空時,系統(tǒng)鎖住節(jié)點(diǎn)數(shù)組,并從低到高地一個一個將磁盤上的索引節(jié)點(diǎn)號填入節(jié)點(diǎn)數(shù)組中,直到節(jié)點(diǎn)數(shù)組滿額或再也找不到空閑
18、節(jié)點(diǎn)。在節(jié)點(diǎn)數(shù)組滿額的同時,系統(tǒng)記住它所找到的最高序號的節(jié)點(diǎn),并稱之為“銘記”節(jié)點(diǎn)。銘記節(jié)點(diǎn)是保存在節(jié)點(diǎn)數(shù)組中的最后一個節(jié)點(diǎn)(最大) ,如果系統(tǒng)分配到銘記節(jié)點(diǎn)時,則啟動 I/O設(shè)備,從銘記節(jié)點(diǎn)開始,重新搜索磁盤上的空閑節(jié)點(diǎn),然后寫進(jìn)i結(jié)點(diǎn)數(shù)組。這可以確保系統(tǒng)不浪費(fèi)時間去讀那些已不含空閑節(jié)點(diǎn)的磁盤塊。,其次是在系統(tǒng)為新建立的文件分配磁盤節(jié)點(diǎn)和內(nèi)存節(jié)點(diǎn)之后,要檢查所分配的節(jié)點(diǎn)是否是真正的空閑節(jié)點(diǎn)。如果不是空閑節(jié)點(diǎn),則要放棄本次分配。至于為什么會出現(xiàn)分配到已分配節(jié)點(diǎn)的情況,則主要是由于資源共享引起的。 綜上所述,可將算法 ialloc 描述如下:,ialloc:輸入:文件系統(tǒng)設(shè)備號,文件屬性,聯(lián)接該
19、文件的目錄數(shù) 輸出:上鎖的磁盤節(jié)點(diǎn) begin if i結(jié)點(diǎn)數(shù)組上鎖 then等待開鎖 fi if 節(jié)點(diǎn)數(shù)組空 then 鎖住i結(jié)點(diǎn)數(shù)組 為搜索空閑節(jié)點(diǎn)取銘記節(jié)點(diǎn) 搜索磁盤;將空閑節(jié)點(diǎn)置入節(jié)點(diǎn)數(shù)組 為i結(jié)點(diǎn)數(shù)組解鎖 fi 從節(jié)點(diǎn)數(shù)組中分配一節(jié)點(diǎn) 調(diào)用 iget 分配內(nèi)存節(jié)點(diǎn) if iget返回的內(nèi)存節(jié)點(diǎn)為非空閑節(jié)點(diǎn) then 把該節(jié)點(diǎn)的內(nèi)容寫回磁盤;釋放該節(jié)點(diǎn); 重新申請磁盤節(jié)點(diǎn) else 將 iget 返回的內(nèi)存節(jié)點(diǎn)初始化 將內(nèi)容寫回磁盤節(jié)點(diǎn) 空閑節(jié)點(diǎn)數(shù)減 fi end,磁盤節(jié)點(diǎn)的釋放過程 ifree是 ialloc 的反過程。但相對來說,ifree 比較簡單。ifree 首先把空閑節(jié)點(diǎn)數(shù)加
20、,如果超級塊的節(jié)點(diǎn)數(shù)組未被鎖住且有空表項(xiàng),則 ifree把釋放的節(jié)點(diǎn)號放入節(jié)點(diǎn)數(shù)組后返回。如果節(jié)點(diǎn)數(shù)組已處于滿額狀態(tài),則 ifree將新釋放的節(jié)點(diǎn)與銘記節(jié)點(diǎn)相比校。如果新釋放的節(jié)點(diǎn)小于銘記節(jié)點(diǎn),則 ifree將新釋放的節(jié)點(diǎn)作為銘記節(jié)點(diǎn),并丟掉原來的銘記節(jié)點(diǎn),否則丟掉新釋放的節(jié)點(diǎn)(為什么?)。如果超級塊節(jié)點(diǎn)數(shù)組是被鎖住的,則此時系統(tǒng)正在進(jìn)行磁盤節(jié)點(diǎn)搜索工作。ifree 直接返回,以避免競爭條件(有可能漏掉節(jié)點(diǎn))。,9.3.2 內(nèi)存節(jié)點(diǎn)的分配與釋放 當(dāng)系統(tǒng)打開文件并對其進(jìn)行搜索、讀寫等操作時,為相應(yīng)的文件分配一個內(nèi)存節(jié)點(diǎn),以便把對應(yīng)磁盤節(jié)點(diǎn)信息復(fù)制到內(nèi)存。一般來說,當(dāng)系統(tǒng)創(chuàng)建一個文件之后,如果未關(guān)
21、閉該文件的話,則該文件已擁有了相應(yīng)的內(nèi)存節(jié)點(diǎn)。此時,如果用戶要對該文件進(jìn)行相應(yīng)的操作的話,系統(tǒng)只需增加已有內(nèi)存節(jié)點(diǎn)的訪問計數(shù)和做互斥處理即可。 內(nèi)存節(jié)點(diǎn)的分配由過程 iget 完成,iget的輸入是文件系統(tǒng)所在的設(shè)備名和磁盤節(jié)點(diǎn)號。輸出是對應(yīng)的上了鎖的內(nèi)存節(jié)點(diǎn)。 首先,iget根據(jù)給定的磁盤節(jié)點(diǎn)號從內(nèi)存節(jié)點(diǎn)數(shù)組中搜索相應(yīng)的內(nèi)存節(jié)點(diǎn)。,如果該節(jié)點(diǎn)已在內(nèi)存,則只需增加引用計數(shù)并鎖定該節(jié)點(diǎn)即可。否則,應(yīng)從內(nèi)存節(jié)點(diǎn)數(shù)組中分配一個節(jié)點(diǎn)并啟動設(shè)備,將對應(yīng)磁盤節(jié)點(diǎn)信息復(fù)制到內(nèi)存節(jié)點(diǎn)后上鎖返回。 另外,當(dāng)一個文件被關(guān)閉時,系統(tǒng)釋放其內(nèi)存節(jié)點(diǎn)。UNIX系統(tǒng)中,釋放內(nèi)存節(jié)點(diǎn)的過程是iput。iput首先判內(nèi)存節(jié)點(diǎn)
22、的訪問計數(shù)是否等于,如果訪問計數(shù)等于的話,則表示當(dāng)前沒有其他用戶使用該文件,只需把內(nèi)存節(jié)點(diǎn)項(xiàng)的內(nèi)容復(fù)制回磁盤節(jié)點(diǎn)后就可釋放該內(nèi)存節(jié)點(diǎn)項(xiàng)。如果訪問計數(shù)大于,則只需將訪問計數(shù)減即可。 再者,如果表示與該文件相聯(lián)接的目錄數(shù)的聯(lián)接計數(shù)值為的話,則表示該文件已不再需要,iput釋放與該文件有關(guān)的所有磁盤塊和磁盤節(jié)點(diǎn)。,9.3.3 系統(tǒng)打開文件表的分配與釋放 在 UNIX 系統(tǒng)中,用戶之間除了采用存取權(quán)限控制方式共享文件信息之外,對于享有存取權(quán)限的用戶,還可以采用如下方式共享文件:子進(jìn)程共享父進(jìn)程打開的所有文件;由系統(tǒng)調(diào)用 link 將不同的文件進(jìn)行聯(lián)接等。對于這些不同的共享方式,用戶和系統(tǒng)都需要有相應(yīng)的
23、數(shù)據(jù)結(jié)構(gòu)與之相應(yīng)。UNIX系統(tǒng)中設(shè)置有系統(tǒng)打開文件表,存放各進(jìn)程共享同一文件時的讀寫指針;用戶打開文件表通過指針fp指向系統(tǒng)打開文件表。 用戶在讀寫、打開一個文件時,首先由iget在內(nèi)存i節(jié)點(diǎn)數(shù)組中分配一空閑項(xiàng),并根據(jù)用戶提供的文件名,找到與此文件對應(yīng)的磁盤i節(jié)點(diǎn),然后將磁盤i節(jié)點(diǎn)復(fù)制到已分得的內(nèi)存i節(jié)點(diǎn)中。,此時,i節(jié)點(diǎn)訪問計數(shù)等于1。如果磁盤i節(jié)點(diǎn)已在內(nèi)存中,則對i節(jié)點(diǎn)訪問計數(shù)加1。接著系統(tǒng)在系統(tǒng)打開文件表中為訪問該文件的用戶分配一系統(tǒng)打開文件表項(xiàng)。在分得系統(tǒng)打開文件表項(xiàng)后對該表項(xiàng)賦初值以建立系統(tǒng)打開文件表和內(nèi)存i節(jié)點(diǎn)的聯(lián)系。同時,在用戶打開文件表中填寫指向系統(tǒng)打開文件表的指針fp和把對應(yīng)
24、的用戶打開文件表項(xiàng)的序號fd送給用戶。經(jīng)過上述操作,兩個以上的用戶共享某一文件時,將會分配得到與用戶數(shù)相等的系統(tǒng)打開文件表項(xiàng),且這些表項(xiàng)指向同一內(nèi)存i節(jié)點(diǎn)。但在父、子進(jìn)程共享同一文件時,由于子進(jìn)程是直接繼承父進(jìn)程打開文件,因此,i節(jié)點(diǎn)訪問計數(shù)不變。,為了指明父、子進(jìn)程共享同一文件的情況,在系統(tǒng)打開文件表項(xiàng)中設(shè)有共享文件計數(shù)項(xiàng)以指明父、子進(jìn)程的個數(shù)。系統(tǒng)打開文件表項(xiàng)的分配由過程getf完成。 關(guān)閉文件時,根據(jù)用戶提供的文件標(biāo)識符fd找到對應(yīng)的用戶打開文件表項(xiàng),從而得到指向系統(tǒng)打開文件表的指針fp。然后就可清除用戶打開文件表項(xiàng)和把系統(tǒng)打開文件表項(xiàng)共享文件計數(shù)項(xiàng)減1。JP1當(dāng)共享計數(shù)項(xiàng)為0時,則清除
25、系統(tǒng)打開文件表項(xiàng)和將內(nèi)存i節(jié)點(diǎn)中共享計數(shù)項(xiàng)減1。用戶打開文件表項(xiàng)和系統(tǒng)打開文件表項(xiàng)的釋放分別由過程close和closef完成。,9.3.4 地址映射 UNIX系統(tǒng)采用索引結(jié)構(gòu)存放文件物理塊的地址。即在文件對應(yīng)的i節(jié)點(diǎn)中,放有存放文件物理塊號的索引結(jié)構(gòu)。由對應(yīng)文件的邏輯字節(jié)偏移量計算出邏輯塊號之后,就可搜索內(nèi)存i節(jié)點(diǎn)中的地址索引結(jié)構(gòu)而得到文件的物理塊號。UNIX system 把常規(guī)文件分為小型、中型、大型和巨型4種。文件長度小于5K的為小型文件。對于小型文件,索引數(shù)組中的前30個字節(jié)被用來存放其物理塊塊號。文件長度大于5K但小于90K的文件為中型文件。對于中型文件,i節(jié)點(diǎn)的索引數(shù)組所指的前1
26、0個物理塊中存放文件信息,而索引數(shù)組所指的第11個物理塊中存放的則是存放文件信息的物理塊塊號(不包括前10個物理塊塊號)。,文件長度大于90K但小于14.54M的文件為大型文件。于大型文件,UNIX System 采用二次間接尋址的方法。即索引數(shù)組的和經(jīng)第12項(xiàng)所指的物理塊中存放的既不是文件信息,也不是存放文件信息的物理塊號,而是那些進(jìn)行二次間接存放文件信息的物理塊號。 對于更大的文件,稱之為巨型文件。巨型文件采用三次間接的辦法存放。 索引數(shù)組中的直接塊和間接塊的關(guān)系如圖9.5所示。 在用戶進(jìn)程搜索文件時,根據(jù)相應(yīng)的i節(jié)點(diǎn)信息,可根據(jù)上述地址變換關(guān)系由邏輯文件中的相對地址找到實(shí)際文件信息所在的
27、物理塊。該轉(zhuǎn)換算法由過程bmap完成。,圖9.5 文件映射關(guān)系,9.4 目錄與搜索方法 UNIX系統(tǒng)中的目錄文件是以普通文件存放,且文件的目錄和說明信息采用了SFD和BFD結(jié)構(gòu)方式以利于共享。這樣,當(dāng)用戶搜索當(dāng)前目錄下的文件時,可以直接從當(dāng)前目錄開始搜索,而當(dāng)被搜索文件不在當(dāng)前目錄下時,則從根目錄開始按指定路徑搜索(已做過聯(lián)接的其他目錄下的文件被看作當(dāng)前目錄下文件)。由于UNIX的文件系統(tǒng)采用樹型結(jié)構(gòu),且只有最低一級的葉才代表文件信息,因此,對文件信息的搜索的大部分工作是對i節(jié)點(diǎn)和對目錄文件的搜索。 UNIX System 對內(nèi)存i節(jié)點(diǎn)的搜索采用散列搜索法。,首先,系統(tǒng)把空閑內(nèi)存i節(jié)點(diǎn)組成一個
28、頭指針為ifreelist鏈的鏈表,而已分配的內(nèi)存i節(jié)點(diǎn)則按給定的散列函數(shù)分成不同的組。系統(tǒng)定義的散列函數(shù)為ihash(x)=,其中,i_forw 是內(nèi)存i節(jié)點(diǎn)中定義的散列函數(shù)指針,有了該項(xiàng)就可使散列隊列與相應(yīng)的i節(jié)點(diǎn)對應(yīng)起來。 顯然,只要給定了i節(jié)點(diǎn)號,就可由上述散列函數(shù)找到該i節(jié)點(diǎn)所在散列隊列的頭指針地址。然后,可進(jìn)一步采用順序搜索法從該散列隊列中找出所要搜索的i節(jié)點(diǎn)地址。 至于對目錄文件的搜索,即從目錄文件中找到與指定分量相匹配的文件名的搜索,則采用順序搜索法。這是因?yàn)橐粋€目錄文件中的內(nèi)容總是較少的,從而不會占用太多的搜索時間。 對文件的存取搜索是通過過程namei完成的。namei將給
29、定的路徑名轉(zhuǎn)換為所要搜索文件的內(nèi)存i節(jié)點(diǎn)指針。,首先,namei判定搜索路徑名是從根目錄開始的絕對路徑名,還是從當(dāng)前目錄開始的相對路徑名。如果是絕對路徑名,則將根目錄置為目錄變量,否則將當(dāng)前目錄置為目錄變量。其次,namei以目錄變量為依據(jù),搜索到該目錄變量所對應(yīng)的內(nèi)存i節(jié)點(diǎn),并驗(yàn)證存取許可權(quán)。如果該目錄文件是可以存取的,則依次將該目錄變量所對應(yīng)的目錄文件塊讀入內(nèi)存,并且順序搜索與路徑名中目錄變量的下一個分量相匹配的文件名。如果未找到相應(yīng)的分量,則表明文件系統(tǒng)中不存在相應(yīng)的文件或路徑名有錯。否則,如果路徑名未搜索完畢的話,則namei反復(fù)將目錄變量沿路徑名下移,且重復(fù)從搜索目錄變量對應(yīng)i節(jié)點(diǎn)開
30、始的上述操作。當(dāng)路徑名搜索完畢,且已找到對應(yīng)文件名時,返回該文件名所對應(yīng)的內(nèi)存i節(jié)點(diǎn)指針。,算法namei可描述如下: namei : 輸入 : 路徑名 輸出 : 上了鎖的內(nèi)存i節(jié)點(diǎn) begin if 路徑名從根目錄開始 then 目錄變量 = 根目錄 i節(jié)點(diǎn)變量 = 根i節(jié)點(diǎn) else 目錄變量 = 當(dāng)前目錄 i節(jié)點(diǎn)變量 = 當(dāng)前目錄i節(jié)點(diǎn) fi while(還有路徑分量未搜索完畢) do 目錄變量 = 下一個分量 驗(yàn)證存取權(quán)限 根據(jù)i節(jié)點(diǎn)變量中的說明信息,讀入對應(yīng)的目錄文件塊 順序搜索目錄文件塊中的項(xiàng) if 目錄文件塊中的一個登記項(xiàng)與目錄變量相同 then 得到目錄變量的內(nèi)存i節(jié)點(diǎn)號 釋放
31、i節(jié)點(diǎn)變量中的i節(jié)點(diǎn) 散列法搜索內(nèi)存i節(jié)點(diǎn) i節(jié)點(diǎn)變量 = 目錄變量對應(yīng)的i節(jié)點(diǎn) else 目錄中無該分量,返回有關(guān)信息 fi i節(jié)點(diǎn)變量中i節(jié)點(diǎn)上鎖返回 od end,9.5 文件系統(tǒng)的系統(tǒng)調(diào)用 本節(jié)從用戶使用文件系統(tǒng)的角度介紹文件系統(tǒng)的動作。 UNIX文件系統(tǒng)為用戶提供的系統(tǒng)調(diào)用有打開和關(guān)閉文件用的open與close,創(chuàng)建文件用的creat,對打開文件進(jìn)行讀寫操作的read和write,對文件樹進(jìn)行操作的chdir和chown,改變文件屬性的chown,chmod和有關(guān)文件聯(lián)接的link,unlink以及進(jìn)行通信操作的pipe等。無論用戶使用何種有關(guān)文件系統(tǒng)的系統(tǒng)調(diào)用,都必須指定該系統(tǒng)調(diào)
32、用所要進(jìn)行操作的文件路徑名(文件名)或者文件描述符fd。只有在指定了文件路徑名或文件描述符fd之后,系統(tǒng)調(diào)用才能對有關(guān)文件進(jìn)行操作。,在用戶進(jìn)程使用系統(tǒng)調(diào)用時,首先,執(zhí)行該系統(tǒng)調(diào)用將使得系統(tǒng)產(chǎn)生一條稱為陷阱(trap)指令的信息,從而啟動中斷和陷阱總控程序(后述),使得系統(tǒng)由用戶態(tài)進(jìn)入系統(tǒng)態(tài)執(zhí)行。在陷阱指令啟動中斷和陷阱總控程序的同時,系統(tǒng)調(diào)用的各參數(shù)寫入user結(jié)構(gòu)中對應(yīng)部分。然后,由中斷和陷阱總控程序,系統(tǒng)進(jìn)入執(zhí)行與系統(tǒng)調(diào)用有關(guān)的文件系統(tǒng)內(nèi)部過程和緩沖區(qū)管理過程等。文件系統(tǒng)的系統(tǒng)調(diào)用與其內(nèi)部過程的執(zhí)行關(guān)系如圖9.6所示。 下面,以系統(tǒng)調(diào)用read為例,進(jìn)一步說明系統(tǒng)調(diào)用的執(zhí)行過程。,圖9.
33、6 文件系統(tǒng)的系統(tǒng)調(diào)用與低層算法,在使用系統(tǒng)調(diào)用read之前,準(zhǔn)備進(jìn)行讀操作的文件必須是打開的。也就是說,在read之前必須先使用系統(tǒng)調(diào)用open或creat(非管道文件時),并將該文件的訪問許可權(quán)設(shè)置成可讀的,否則無法進(jìn)行讀操作。在調(diào)用了系統(tǒng)調(diào)用open之后,用戶得到返回的進(jìn)程標(biāo)識符fd,且系統(tǒng)已將所要讀文件的磁盤i節(jié)點(diǎn)復(fù)制到內(nèi)存i節(jié)點(diǎn)中和建立了用戶打開文件表、系統(tǒng)打開文件表與內(nèi)存i節(jié)點(diǎn)之間的聯(lián)系。例如,在系統(tǒng)調(diào)用open打開文件/user/users/zhang后的數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系如圖9.7所示。這里,假定/user/users/zhang已在同一個進(jìn)程中被打開了3次,且每次都設(shè)有不同的
34、讀寫權(quán)限。,圖9.7 打開文件的數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系 顯然,在圖9.7例中,可以用文件標(biāo)識符fd1、fd2或fd3讀文件“/user/users/zhang”。設(shè)用文件標(biāo)識符fd1將count個字符讀到內(nèi)存地址為buffer的工作區(qū)中,則系統(tǒng)調(diào)用read的調(diào)用格式為,read(fd1,buffer,count); 在系統(tǒng)執(zhí)行該系統(tǒng)調(diào)用時,首先產(chǎn)生陷阱指令而進(jìn)入硬件陷阱處理機(jī)構(gòu),并根據(jù)包含陷阱向量入口地址的中斷與陷阱總控程序來選擇相應(yīng)的處理程序和調(diào)用文件系統(tǒng)的低層程序。在陷阱指令發(fā)生后,硬件將有關(guān)參數(shù)從用戶區(qū)送到user結(jié)構(gòu)的u.u_arg數(shù)組中,以便系統(tǒng)調(diào)用程序在核心棧上執(zhí)行時能夠使用這些參數(shù)。
35、在執(zhí)行read調(diào)用時,置入u.u_arg的參數(shù)是buffer和count等。除此之外,系統(tǒng)還將user結(jié)構(gòu)中的讀寫方式設(shè)置為“讀”,以及將user結(jié)構(gòu)中的偏移量設(shè)置為系統(tǒng)打開文件表中讀指針?biāo)傅闹狄员阒该髯x該文件時的起始位置。,在設(shè)置了有關(guān)參數(shù)之后,系統(tǒng)由fd1找到fp1,并由fp1找到對應(yīng)的內(nèi)存i節(jié)點(diǎn)。該搜索過程由過程getf完成。在找到了對應(yīng)的內(nèi)存i節(jié)點(diǎn)之后,為了避免競爭條件,系統(tǒng)將該i節(jié)點(diǎn)鎖定之后進(jìn)入讀操作。 讀操作是一個循環(huán)過程。系統(tǒng)首先用算法bmap將文件的字節(jié)偏移量映射為磁盤塊塊號,并計算出在該塊中的起始位置和應(yīng)讀寫字符長度。在把該塊讀入內(nèi)存用戶地址buffer之后,系統(tǒng)根據(jù)已讀入
36、的字符數(shù),修改user結(jié)構(gòu)中的有關(guān)參數(shù),然后重復(fù)讀操作過程,直到完全滿足用戶要求或fd1所指文件中不再含有數(shù)據(jù)。 讀操作過程是由后述設(shè)備管理程序完成的。 系統(tǒng)調(diào)用read的實(shí)現(xiàn)過程可描述如下:,read : 輸入 : 文件描述符fd 用戶內(nèi)存地址buffer 要讀字節(jié)數(shù)count 輸出 :復(fù)制到用戶區(qū)的字節(jié)數(shù) begin 在user結(jié)構(gòu)中設(shè)置用戶區(qū)地址,字節(jié)偏移與字節(jié)計數(shù)等 由文件描述符fd得到系統(tǒng)打開文件表指針 檢查文件的可存取性 由系統(tǒng)打開文件表得到內(nèi)存i節(jié)點(diǎn)指針 鎖定內(nèi)存i節(jié)點(diǎn) repeat 將磁盤中數(shù)據(jù)讀入內(nèi)存buffer中 until 讀完count字節(jié)或文件中不再存在字符 將內(nèi)存i
37、節(jié)點(diǎn)解鎖 返回已讀入字符總數(shù) end,9.6 UNIX System 的中斷和陷阱總控程序 1. 中斷和陷阱總控過程 通常,在系統(tǒng)執(zhí)行期間內(nèi),系統(tǒng)內(nèi)發(fā)生的一些突發(fā)事件要求處理機(jī)改變其控制流程去執(zhí)行處理這些突發(fā)事件的特定軟件。這些突發(fā)事件被分為兩類:與當(dāng)前執(zhí)行進(jìn)程有關(guān)的事件稱為陷入或陷阱,例如系統(tǒng)調(diào)用指令、指令錯、溢出等;與當(dāng)前執(zhí)行進(jìn)程無關(guān)但與整個系統(tǒng)或其他進(jìn)程有關(guān)的事件稱為中斷,例如I/O數(shù)據(jù)傳送完成、時間片到等事件。 在UNIX System 中,系統(tǒng)對中斷和陷阱的處理既有相同的一面,又有不同的一面。,系統(tǒng)中有一個稱為陷阱和中斷向量表的系統(tǒng)控制塊SCB。SCB中存放有由陷阱和中斷處理程序的入
38、口地址和對應(yīng)的陷阱或中斷名組成的陷阱或中斷向量。SCB的部分內(nèi)容如圖9.8所示。 當(dāng)陷阱或中斷發(fā)生時,處理機(jī)將自動地根據(jù)陷阱或中斷名找到對應(yīng)處理程序的入口地址,從而轉(zhuǎn)入去執(zhí)行相應(yīng)的處理程序。中斷和陷阱總控程序就是用來完成上述功能的。,圖9.8 部分陷阱和中斷向量,中斷和陷阱處理的不同方面則包括以下幾點(diǎn)。首先,由于中斷是與整個系統(tǒng)或非當(dāng)前執(zhí)行進(jìn)程有關(guān)的,其處理程序只能在系統(tǒng)的中斷棧上執(zhí)行。反之,由于陷阱是與當(dāng)前進(jìn)程有關(guān)的事件,可以在當(dāng)前執(zhí)行進(jìn)程的核心棧上執(zhí)行有關(guān)陷阱處理程序。再者,為了對不同的中斷和陷阱做出不同的反應(yīng),系統(tǒng)對每個中斷和陷阱設(shè)置有相應(yīng)的優(yōu)先級。當(dāng)處理機(jī)轉(zhuǎn)入陷阱處理時,由于陷阱處理不
39、做進(jìn)程切換,因此,處理機(jī)狀態(tài)字中的中斷優(yōu)先級一般不用改變。但是,在有中斷請求時,系統(tǒng)只響應(yīng)那些優(yōu)先級高于狀態(tài)字中的中斷優(yōu)先級的中斷。至于那些優(yōu)先級低于狀態(tài)字中的中斷優(yōu)先級的中斷,則被屏蔽。,因此,一般來說,進(jìn)入陷阱處理程序與處理機(jī)狀態(tài)字中的中斷優(yōu)先級無關(guān),而中斷處理程序則只有處理機(jī)狀態(tài)字中的中斷優(yōu)先級低于請求中斷的中斷優(yōu)先級時才能進(jìn)入。 中斷和陷阱處理總控程序就是在系統(tǒng)內(nèi)發(fā)生了中斷或陷阱事件之后,根據(jù)中斷和陷阱的處理優(yōu)先級,接收來自于硬件中斷或陷阱信號,并控制系統(tǒng)轉(zhuǎn)入相應(yīng)處理過程以及恢復(fù)現(xiàn)場的程序模塊。在UNIX System 中,中斷和陷阱總控程序由一個用匯編語言編寫成的程序trap.s構(gòu)成
40、。顯然,用匯編語言編寫中斷和陷阱總控程序的目的是出于提高效率和與硬件接口方便的考慮。 總控程序含有幾乎全部中斷與陷阱向量的入口地址。,2. 中斷分類 UNIX System 對中斷作分類處理, 被分為5類: (1) 進(jìn)程調(diào)度中斷 進(jìn)程調(diào)度中斷是一個由軟件事件引起的中斷。由于System 的調(diào)度程序在進(jìn)程0的核心棧上執(zhí)行,在中斷?;蚝诵臈I蠄?zhí)行的核心程序都不能直接調(diào)用進(jìn)程調(diào)度程序。從而, 在系統(tǒng)處理中斷或陷阱的過程中,若時鐘片到等事件使得調(diào)度標(biāo)志runrun被設(shè)置時,則在中斷或陷阱處理結(jié)束時,產(chǎn)生進(jìn)程調(diào)度中斷信號并調(diào)用過程Xreshed進(jìn)行調(diào)度處理。 (2) 時鐘中斷 主要是間隔時鐘中斷。時鐘計
41、數(shù)器以微秒為單位遞增。,當(dāng)計數(shù)器的值計數(shù)到16,667微秒時,產(chǎn)生一次時鐘中斷以啟動時鐘中斷處理程序。 當(dāng)時鐘中斷發(fā)生60次,也就是累計時間達(dá)到1秒時,中斷處理程序設(shè)置調(diào)度標(biāo)志runrun和計算各進(jìn)程的優(yōu)先級等。 (3) 電源失效和恢復(fù) (4) 機(jī)器故障中斷 這幾種中斷的主要目的是進(jìn)行現(xiàn)場保護(hù)與恢復(fù),以及有關(guān)檢驗(yàn)等。因此,電源失效和機(jī)器故障中斷都享有較高的優(yōu)先級。 (5) 設(shè)備中斷 設(shè)備中斷程序包括控制臺中斷、單總線適配器中斷和多總線適配器中斷等部分。,3. 中斷處理 中斷處理包括三個部分,即通過總控程序進(jìn)入中斷處理子程序;中斷處理子程序進(jìn)行中斷處理;退出中斷。盡管中斷和陷阱向量的入口地址都放
42、在中斷和陷阱總控程序trap.s中,但在中斷和陷阱處理程序的進(jìn)入與退出方式上,二者的處理方法是不相同的。這是因?yàn)橄葳逄幚硪笙葳灏l(fā)生指令與處理子程序之間傳遞較多的參數(shù),且中斷處理子程序與陷阱處理子程序在不同的堆棧上執(zhí)行。 進(jìn)入中斷處理時,trap.s除了用一條匯編指令保護(hù)有關(guān)寄存器(現(xiàn)場)的內(nèi)容之外,沒有公共的入口處理程序,各中斷向量的入口處理也非常簡單,只需用幾條過程調(diào)用指令就可實(shí)現(xiàn)。例如控制臺磁帶機(jī)接收中斷的入口處理程序?yàn)?,Xcdtrint: calls $0,_catrint brb int_ret1 其中,Xcdtrint為中斷向量;calls是過程調(diào)用指令;_catrint是被調(diào)用
43、過程名;而$0則表示發(fā)生中斷處理時傳遞給被調(diào)用過程的參數(shù)個數(shù),$0表示此次中斷處理不需要外部參數(shù)。brb int_ret1則表示中斷處理完畢,處理機(jī)空閑。,不同的中斷對應(yīng)有不同的中斷處理程序。不過,在系統(tǒng)進(jìn)行中斷處理后退出中斷以及恢復(fù)被保護(hù)現(xiàn)場部分的程序是一段公用代碼。在這段代碼中,首先,系統(tǒng)恢復(fù)有關(guān)通用寄存器,并置處理機(jī)空閑標(biāo)志。然后,若中斷是在用戶態(tài)下發(fā)生且設(shè)置有再調(diào)度標(biāo)志runrun,則請求進(jìn)程調(diào)度中斷將用戶態(tài)改為核心態(tài)以便執(zhí)行調(diào)度程序。如果沒有設(shè)置runrun再調(diào)度標(biāo)志,或中斷發(fā)生在核心態(tài)下,則系統(tǒng)返回原被中斷處繼續(xù)執(zhí)行。,4. 陷阱處理 與中斷處理時不同, UNIX System 中
44、含有公共的陷阱入口處理程序。首先,trap.s中的有關(guān)程序區(qū)別所發(fā)生的陷阱類型,并將陷阱的類型值和有關(guān)參數(shù)壓入堆棧。然后,調(diào)用公共的入口處理程序處理各種不同的陷阱。 UNIX System 可處理12種不同的陷阱。即: SYSCALL 更換到核心態(tài)方式(系統(tǒng)調(diào)用) SEGFLT 轉(zhuǎn)換無效 PROTFLT 訪問違章 PRIVFLT 非法指令 RSADFLT 保留尋址方式 RSOPFLT 保留操作數(shù),ARTHRP 算術(shù)自陷 TRCTRAP 跟蹤自陷 BPTFLT 斷點(diǎn)故障指令 XFCFLT 擴(kuò)展功能調(diào)用指令 CMPTFLT 兼容方式 RESCHED 進(jìn)程調(diào)度中斷 對上述12種陷阱處理可根據(jù)其發(fā)生的
45、時機(jī)分為兩種情況:即核心態(tài)方式下的陷阱處理和用戶態(tài)方式下的陷阱處理。,由于UNIX系統(tǒng)規(guī)定,核心程序不使用系統(tǒng)調(diào)用,以及UNIX System 的核心程序不搞請求調(diào)頁,即所有的核心代碼全部在內(nèi)存,從而上述各種陷阱一般不會在核心態(tài)方式下發(fā)生。如果在核心態(tài)方式下發(fā)生了陷阱,則系統(tǒng)認(rèn)為是出現(xiàn)了故障,從而打印出一些用戶現(xiàn)場信息之后進(jìn)入死循環(huán),等待系統(tǒng)管理人員干預(yù)。 用戶態(tài)下的陷阱處理可進(jìn)一步分為三種情況,即系統(tǒng)調(diào)用、地址轉(zhuǎn)換無效和用戶自定義處理(軟中斷處理)方式。 上述陷阱處理的公共程序是一個名為trap的過程。其調(diào)用形式為: trap(sp,type,code,pc,ps),其中,sp為發(fā)生陷阱的進(jìn)
46、程用戶棧指針,type指明陷阱類型,code是確定系統(tǒng)調(diào)用序號的代碼操作數(shù),pc為程序計數(shù)器的內(nèi)容,ps為處理機(jī)狀態(tài)長字。trap過程的處理流程如圖9.9所示。 在圖9.9中,除了SYSCALL和SEGFLT(地址轉(zhuǎn)換無效)和RESCHED(進(jìn)程調(diào)度)三種陷阱之外,其他9種陷阱都已轉(zhuǎn)換成軟中斷方式處理。其中各種軟中斷所使用的信號定義如下: SIGILL非法指令 SIGTRAP跟蹤陷入 SIGBUS訪問違章 SIGFPE算術(shù)陷入 SIGSEGV轉(zhuǎn)換無效 SIGEMT XFC指令故障,圖9.9 trap程序處理流程圖,系統(tǒng)提供標(biāo)準(zhǔn)軟中斷程序進(jìn)行處理。圖9.9中有關(guān)SEGFLT的處理是針對Syste
47、m 早期版本的。當(dāng)進(jìn)程訪問到一個不在內(nèi)存中的頁面時,硬件將產(chǎn)生轉(zhuǎn)換無效故障。在System 早期版本中,由于未采用請求調(diào)頁技術(shù),即進(jìn)程在執(zhí)行前將所需頁面全部調(diào)入內(nèi)存,從而產(chǎn)生轉(zhuǎn)換無效的原因只能是用戶棧滿引起的。因此,系統(tǒng)首先進(jìn)行用戶棧擴(kuò)充,如成功則進(jìn)程繼續(xù)執(zhí)行,否則系統(tǒng)向該進(jìn)程發(fā)生轉(zhuǎn)換無效信號。 圖9.9中的另一種陷阱處理是有關(guān)系統(tǒng)調(diào)用的處理。由于系統(tǒng)調(diào)用的處理需要更進(jìn)一步調(diào)用核心程序來完成用戶所要求的功能,因此,系統(tǒng)調(diào)用的處理由如下幾步組成:,(1) 確定系統(tǒng)調(diào)用序號i。 系統(tǒng)調(diào)用序號i由下式確定: i = code 二是緩沖區(qū)的隊列構(gòu)造,利用這些構(gòu)造,可以方便地對緩沖區(qū)進(jìn)行操作。 緩沖控制
48、塊和緩沖數(shù)據(jù)區(qū)間具有一一對應(yīng)的映射關(guān)系,除了討論緩沖控制塊時之外,把緩沖控制塊和緩沖區(qū)統(tǒng)稱為緩沖區(qū)。緩沖控制塊的構(gòu)成如圖9.10。,圖9.10 緩沖控制塊的結(jié)構(gòu),圖9.10所示的緩沖控制塊中包含了一個邏輯設(shè)備號和該緩沖區(qū)所對應(yīng)的邏輯磁盤數(shù)據(jù)塊號。另外,緩沖控制塊除了包含有指向緩沖數(shù)據(jù)區(qū)的指針之外,還包含有兩組用來構(gòu)成不同緩沖隊列結(jié)構(gòu)的指針。這些指針和隊列將在后續(xù)部分中解釋。再者,緩沖控制塊中的狀態(tài)部分指明該緩沖區(qū)當(dāng)前所處的狀態(tài)。這些狀態(tài)是如下條件的組合。緩沖區(qū)當(dāng)前為“上鎖”或“開鎖”狀態(tài);緩沖區(qū)是否包含有效數(shù)據(jù);系統(tǒng)在把該緩沖區(qū)分配出去之前是否必須把緩沖區(qū)中內(nèi)容寫到磁盤上(延遲寫);系統(tǒng)當(dāng)前是
49、否正在從磁盤往磁盤緩沖區(qū)讀信息或把緩沖區(qū)的內(nèi)容寫到磁盤上;以及一個進(jìn)程是否正在等待該緩沖區(qū)變?yōu)殚_鎖等。,顯然,由于緩沖區(qū)是獨(dú)享資源,從而不允許多個進(jìn)程同時對一個緩沖區(qū)進(jìn)行操作,因此緩沖控制塊中設(shè)有鎖定位。另外,一個磁盤塊在同一時間內(nèi)也不能映射到多個緩沖區(qū)上;否則,系統(tǒng)將會不知道哪一個緩沖區(qū)中包含著當(dāng)前數(shù)據(jù)而產(chǎn)生讀寫錯誤。 緩沖池結(jié)構(gòu)由多個緩沖區(qū)隊列組成,包括空閑緩沖區(qū)隊列、設(shè)備緩沖區(qū)隊列和設(shè)備I/O請求隊列等。 空閑緩沖隊列又稱空閑av隊列,它是系統(tǒng)所擁有的所有空閑緩沖區(qū)資源。在系統(tǒng)初始化時,所有的緩沖區(qū)按序號高低掛在空閑av隊列上。當(dāng)文件系統(tǒng)申請一個緩沖區(qū)時,從空閑av隊列首部取下一個緩沖區(qū)
50、,而一個緩沖區(qū)被釋放時則掛入空閑av隊列末尾。圖9.11給出了空閑av隊列的構(gòu)成情況。,圖9.11 空閑緩沖隊列結(jié)構(gòu),設(shè)備緩沖區(qū)隊列又稱設(shè)備b鏈。設(shè)備b鏈鏈接所有分配給各類設(shè)備使用的緩沖區(qū)。每類設(shè)備都有自己的設(shè)備b鏈,每類設(shè)備的設(shè)備b鏈按散列算法組成64個隊列,每個隊列頭部都有自己的頭標(biāo)。 當(dāng)系統(tǒng)為一個設(shè)備b_dev中的邏輯塊號b分配一個緩沖區(qū)之后,若系統(tǒng)要存取一個設(shè)備b_dev上的邏輯塊b時,利用下面散列算法構(gòu)成或搜索散列隊列: i=( b_dev + b ) mod 64 其中i為散列隊列頭標(biāo)。設(shè)備b鏈的結(jié)構(gòu)如圖9.12。 在圖9.12所示的設(shè)備b鏈結(jié)構(gòu)中,省略了邏輯設(shè)備號b_dev。而且
51、,每個散列隊列頭標(biāo)對應(yīng)著一個塊號以64取模后的余數(shù)所組成的緩沖區(qū)隊列,這些緩沖區(qū)既可能是空閑的,也可能正在被使用。,圖9.12 設(shè)備b鏈結(jié)構(gòu),為什么要將一個空閑緩沖區(qū)同時掛在空閑av隊列和設(shè)備b鏈隊列中的理由是: 當(dāng)系統(tǒng)需要存取某個磁盤的數(shù)據(jù)時,為了減少啟動設(shè)備的次數(shù),總是先從設(shè)備緩沖b鏈中尋找與之相對應(yīng)的數(shù)據(jù)塊。如果該塊不在b鏈中,則從空閑av鏈中按最近最少使用算法,摘下一空閑緩沖區(qū),改寫緩沖控制塊中的塊號之后掛入對應(yīng)的散列隊列,如果該塊已在b鏈中,則系統(tǒng)不必啟動磁盤。與此相似,當(dāng)系統(tǒng)釋放某個緩沖區(qū)時,仍將該緩沖區(qū)放置在設(shè)備b鏈中,緩沖區(qū)內(nèi)的數(shù)據(jù)則一直等到重新往該緩沖區(qū)內(nèi)寫入新數(shù)據(jù)時才釋放。
52、這樣,系統(tǒng)就可從設(shè)備b鏈中搜索到所有使用過的,但未被改寫的特定緩沖區(qū)。,設(shè)備I/O請求隊列又稱塊設(shè)備av鏈。每個物理塊設(shè)備都有一個I/O請求隊列,設(shè)備I/O請求隊列中的緩沖區(qū)屬于設(shè)備b鏈,但不屬于空閑av隊列。設(shè)備I/O請求隊列是由正在請求該塊設(shè)備進(jìn)行讀寫操作的緩沖區(qū)所組成的隊列,其中的緩沖區(qū)使用與前面所述的緩沖控制塊不完全相同的I/O緩沖控制塊,以指示物理設(shè)備是否正在使用以及有關(guān)寄存器的地址等。 設(shè)備I/O請求隊列為單向隊列。,9.7.2 緩沖區(qū)的分配與釋放 緩沖區(qū)的分配與釋放包括緩沖區(qū)分配(getblk)、空閑緩沖區(qū)分配(geteblk)以及釋放緩沖區(qū)(brelse)操作。 當(dāng)文件系統(tǒng)試圖
53、檢索某一個數(shù)據(jù)塊時,它首先判定所要存取的邏輯設(shè)備號和邏輯塊號,然后,檢查該數(shù)據(jù)塊是否在緩沖池中。如果不在,則分配給它一個空閑緩沖區(qū)。getblk被用來分配緩沖區(qū)。 在把一個緩沖區(qū)分配給一個對應(yīng)磁盤塊時,將可能出現(xiàn)5種典型情況。即: (1) 該數(shù)據(jù)塊在設(shè)備b鏈的散列隊列中,且緩沖區(qū)是空閑的; (2) 設(shè)備b鏈的散列隊列中不存在對應(yīng)的緩沖區(qū),因此,從空閑av鏈?zhǔn)兹∫粋€緩沖區(qū)分配給該磁盤塊;,(3) 在處理上述(2)時, 如果空閑av鏈的鏈?zhǔn)拙彌_區(qū)是一個標(biāo)上了“延遲寫”(后述)標(biāo)記的緩沖區(qū),則系統(tǒng)必須將該緩沖區(qū)的內(nèi)容寫到磁盤上,并分配下一個緩沖區(qū)后返回。 (4) 系統(tǒng)在散列隊列中找不到該塊,且空閑a
54、v隊列已空時,進(jìn)入等待狀態(tài)。 (5) 系統(tǒng)在散列隊列中找到了對應(yīng)的數(shù)據(jù)塊的緩沖區(qū),但此時該緩沖區(qū)已被鎖定,系統(tǒng)仍進(jìn)入睡眠狀態(tài)等待該緩沖區(qū)變?yōu)榭臻e。 geteblk算法用來從空閑av隊列中取一個緩沖區(qū)。首先檢查空閑av隊列是否為空,若為空時睡眠等待。另外,如果空閑av隊列中取下的緩沖區(qū)為延遲寫的話,需將該緩沖區(qū)的數(shù)據(jù)塊先寫回磁盤。geteblk算法用來把空閑av隊列中的緩沖區(qū)鏈入設(shè)備b鏈隊列。,當(dāng)系統(tǒng)不再需要一個緩沖區(qū),或當(dāng)I/O操作完成時,系統(tǒng)調(diào)用brelse算法釋放該緩沖區(qū)。當(dāng)系統(tǒng)釋放一個緩沖區(qū)之后,它喚醒那些因?yàn)榭臻eav隊列空而睡眠的進(jìn)程。,9.7.3 緩沖區(qū)數(shù)據(jù)讀寫 對緩沖區(qū)的讀寫包括來
55、自于兩個方面。第一是從磁盤塊到緩沖區(qū)的讀寫,第二是從緩沖區(qū)到內(nèi)存用戶區(qū)的數(shù)據(jù)流動。其中,緩沖區(qū)和內(nèi)存用戶區(qū)之間的數(shù)據(jù)流動由算法iomove完成,而緩沖區(qū)和磁盤塊之間的數(shù)據(jù)流動則由算法bread,breada和bwrite,bdwrite以及bawrite完成。這些算法之間的關(guān)系如圖9.13所示。 首先,iomove是被文件系統(tǒng)有關(guān)讀寫過程所調(diào)用的,iomove把指定的用戶源地址中的指定長度的數(shù)據(jù)復(fù)制到指定的緩沖區(qū)中,另外,也把指定緩沖區(qū)中的數(shù)據(jù)復(fù)制到給定目的地址的內(nèi)存用戶區(qū)中。由于緩沖區(qū)和內(nèi)存用戶區(qū)同在內(nèi)存,因此,緩沖區(qū)和內(nèi)存用戶區(qū)之間的數(shù)據(jù)流動不會出現(xiàn)速度不匹配問題。,圖9.13 緩沖區(qū)的數(shù)
56、據(jù)讀寫,從磁盤塊讀數(shù)據(jù)到緩沖區(qū)有二種方式。一種被稱為一般讀(bread),另一種稱為預(yù)先讀(breada)。一般讀bread過程的輸入是所要讀的邏輯塊號,輸出是含有讀入數(shù)據(jù)的緩沖區(qū)指針。首先,bread調(diào)用算法getblk得到對應(yīng)的緩沖區(qū)。如果該緩沖區(qū)中的數(shù)據(jù)是有效的,則不啟動磁盤設(shè)備返回。否則,經(jīng)設(shè)備驅(qū)動程序啟動磁盤讀,且調(diào)用bread的進(jìn)程因等待讀盤完成而進(jìn)入睡眠狀態(tài),待到讀盤完成后返回緩沖區(qū)指針。 bread過程可描述如下:,bread: 輸入: 邏輯塊號 輸出: 含有數(shù)據(jù)的緩沖區(qū)指針 begin 調(diào)用getblk得到緩沖區(qū) if 緩沖區(qū)中數(shù)據(jù)有效 then 返回緩沖區(qū)指針 fi 啟動磁
57、盤讀 if 讀盤完成 then 返回緩沖區(qū)指針 fi end,預(yù)先讀breada的輸入是立即讀的邏輯塊號和異步讀的邏輯塊號。breada的輸出則是裝有立即讀邏輯塊號所對應(yīng)數(shù)據(jù)塊的緩沖區(qū)指針。breada過程等待立即讀的邏輯塊號讀入緩沖區(qū),并啟動磁盤異步讀邏輯塊。然后返回立即讀的邏輯塊所對應(yīng)的緩沖區(qū)的指針。UNIX系統(tǒng)使用預(yù)先讀方式是因?yàn)樵谝粋€進(jìn)程順序地讀一個文件時,如果系統(tǒng)異步地請求第二個磁盤塊,則一旦需要這部分?jǐn)?shù)據(jù)時,它們將在內(nèi)存緩沖區(qū)中。從而可以提高讀數(shù)據(jù)的速度。 breada可描述如下: breada: 輸入: 立即讀的邏輯塊號和異步讀的邏輯塊號 輸出: 含有立即讀邏輯塊的緩沖區(qū)指針 b
58、egin if 第一塊不在緩沖池中,then 調(diào)用getblk得到緩沖區(qū) if 緩沖區(qū)中數(shù)據(jù)無效 then 啟動磁盤讀 fi fi if 第二塊不在緩沖池中 then 調(diào)用getblk得到緩沖區(qū) if 緩沖區(qū)中數(shù)據(jù)有效 then 釋放緩沖區(qū) else 啟動磁盤讀 fi fi if 第一塊在緩沖池中 then 讀第一塊,返回該緩沖區(qū)指針 fi if 第一個磁盤塊讀完成 then 返回該緩沖區(qū)指針 fi end,這里, 當(dāng)?shù)诙€數(shù)據(jù)塊對應(yīng)的緩沖區(qū)中數(shù)據(jù)有效時, breada應(yīng)釋放該緩沖區(qū),以便下次其他進(jìn)程可以申請得到該緩沖區(qū)。 把一個緩沖區(qū)的內(nèi)容寫到磁盤塊上去的方法與讀時類似。首先,系統(tǒng)通知驅(qū)動程
59、序說有一個緩沖區(qū)的內(nèi)容應(yīng)該被輸出,從而驅(qū)動程序選中對應(yīng)的物理塊以便進(jìn)行寫操作。如果寫是同步的,則調(diào)用者進(jìn)程因等待寫操作完成而進(jìn)入睡眠,且當(dāng)寫操作完成后再釋放緩沖區(qū)。如果寫是異步或延遲寫的,則系統(tǒng)啟動傳輸,但不等待傳輸完成而返回。算法bwrite可描述如下:,bwrite : 輸入 : 緩沖區(qū)指針 begin 啟動磁盤寫 if 緩沖區(qū)標(biāo)志寫是同步進(jìn)行 then 等待傳輸完成后釋放緩沖區(qū) fi if 緩沖區(qū)標(biāo)志延遲寫 then 將該緩沖區(qū)放入空閑av隊列 fi end,bawrite的功能是異步寫一塊。它由驅(qū)動程序啟動傳輸之后,不等傳輸完成而返回。bawrite的輸入是緩沖區(qū)指針。bdwrite的
60、功能則是延遲地寫一塊,且不啟動傳輸而返回。標(biāo)志了延遲寫的緩沖區(qū)要等到bwrite時啟動傳輸設(shè)備而寫到磁盤上。異步寫的目的是提高寫盤速度,而延遲寫的目的則是為了讓數(shù)據(jù)塊在內(nèi)存內(nèi)待盡量多的時間,以減少不必要的I/O操作。但反過來,由于延遲寫沒有立即把數(shù)據(jù)寫入磁盤,當(dāng)系統(tǒng)發(fā)生癱瘓等時將產(chǎn)生磁盤數(shù)據(jù)錯誤。,9.8 塊設(shè)備驅(qū)動 UNIX系統(tǒng)中的設(shè)備可塊設(shè)備和字符設(shè)備。管理這些設(shè)備的程序模塊被稱為I/O子系統(tǒng)。I/O子系統(tǒng)控制完成進(jìn)程與外設(shè)之間的通信任務(wù)。其中,I/O子系統(tǒng)的核心部分是控制外設(shè)的設(shè)備驅(qū)動程序。本節(jié)主要介紹UNIX系統(tǒng)的塊設(shè)備驅(qū)動原理。 從使用方式看,UNIX的塊設(shè)備有三種用法,即用于交換系
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 供應(yīng)鏈管理師持續(xù)改進(jìn)評優(yōu)考核試卷含答案
- 選剝混繭工安全意識模擬考核試卷含答案
- 野生植物監(jiān)測工崗前創(chuàng)新方法考核試卷含答案
- 森林撫育工安全生產(chǎn)能力水平考核試卷含答案
- 塑料熱合工持續(xù)改進(jìn)評優(yōu)考核試卷含答案
- 制漿工QC考核試卷含答案
- 2024年貴陽信息科技學(xué)院輔導(dǎo)員招聘備考題庫附答案
- 整經(jīng)工操作能力模擬考核試卷含答案
- 水上打樁工操作評估測試考核試卷含答案
- 織襪工崗前理論評估考核試卷含答案
- 統(tǒng)編版語文二年級上冊知識點(diǎn)
- 北京師范大學(xué)介紹
- 設(shè)備隱患排查培訓(xùn)
- 國家事業(yè)單位招聘2025中國農(nóng)業(yè)科學(xué)院植物保護(hù)研究所招聘12人筆試歷年參考題庫附帶答案詳解
- 售后技術(shù)服務(wù)流程規(guī)范
- 六性分析報告標(biāo)準(zhǔn)格式與范例
- 餐具分揀裝置的設(shè)計(機(jī)械工程專業(yè))
- 供水管網(wǎng)施工期間居民供水保障方案
- 江蘇省常州市鐘樓區(qū)小學(xué)語文三年級上冊期末檢測卷(含答案)
- 2025年縣司法局行政執(zhí)法協(xié)調(diào)監(jiān)督工作自查報告
- 醫(yī)院科室臺風(fēng)應(yīng)急預(yù)案
評論
0/150
提交評論