1. 程式人生 > >作業系統——I/O裝置管理(2)

作業系統——I/O裝置管理(2)

I/O軟體(與輸入輸出有關的軟體)

為了更好地管理系統中的輸入輸出裝置,我們需要哪一些軟體?這些軟體各自完成什麼樣的功能?它們之間的相互關係、組織結構是什麼?在這些軟體中,程式設計師負責做什麼?作業系統負責做什麼?I/O裝置廠商負責做什麼?

1、I/O軟體的介面

與I/O軟體有關的角色有三個:應用程式的開發人員,作業系統的設計者和I/O裝置廠商。 I/O軟體的介面:一個是應用程式與作業系統之間的介面,另一個是作業系統與I/O裝置之間的介面。

1.1、應用程式與作業系統之間的介面

作業系統 提供一個應用程式程式設計介面(Application Programming  Interface ,API),讓程式設計人員呼叫。 介面的目標:
  • 裝置獨立性:使用者在編寫程式、訪問各種I/O裝置時,無需事先指定特定裝置的型別。
  • 統一命名:用簡單的字串或整數的方式來命名一個檔案或裝置。在UNIX系統中,命名的規則就是路徑名。
  • 阻塞與非阻塞I/O:我們希望作業系統提供的API函式分為兩類,一類是阻塞性的,即程序啟動一個系統呼叫後,會被阻塞起來,直到I/O操作完成。另一類是非阻塞性的,即當程序啟動一個系統呼叫後,不管I/O操作是否完成,都會立即返回。

1.2、作業系統與I/O裝置的介面

在作業系統和裝置驅動之間,也有一個介面。對於每一種I/O裝置來說,它的裝置驅動程式是由硬體廠商提供的。 為了實現裝置的獨立性,作業系統將各種型別的裝置分為三類:塊裝置、字元裝置和網路裝置,併為每一類裝置定義了一個標準介面。

例如:檔案系統處理的就是抽象的塊裝置。檔案系統是作業系統的一部分,它就是位於上層的I/O軟體中,然後它呼叫的就是這些抽象的介面函式,如讀寫一個數據塊。
檔案系統並不會直接去控制I/O操作,也不去管這些介面函式是如何實現的,它就是通過這些抽象的介面函式來與底層的硬體打交道,這樣才能實現裝置的獨立性。 那些在這些介面中都包含哪些函式?
  • 無論是哪一種裝置,無論是塊裝置還是字元裝置,都需要一些共同的介面函式,(雖然函式的具體實現是不一樣的,但是函式的型別是一樣的)例如
open(deviceNumber):啟動裝置,初始化並分配資源,如緩衝區 close( deviceNumber )  :關閉裝置,釋放資源
  • 對於字元裝置,主要的介面函式包括:
read(deviceNumber, buffer, size):從一個位元組流裝置中讀入size個位元組,寫入到buffer緩衝區中。 write(deviceNumber, buffer, size):從buffer緩衝區中取出size個位元組,寫入到一個位元組流裝置中。
  • 對於塊裝置,主要的介面函式包括:
read(deviceNumber, deviceAddr, buffer):從裝置地址deviceAddr處讀入一個數據塊到buffer緩衝區。 write(deviceNumber, deviceAddr, buffer):把buffer中的資料塊寫入到裝置地址deviceAddr。 seek(deviceNumber,, deviceAddress):把裝置的訪問指標定位到正確的位置。

2、I/O軟體的層次結構

I/O軟體的層次結構
               使用者空間的I/O軟體
              裝置獨立的系統軟體
                  裝置驅動程式
                   中斷處理程式
                      硬體

2.1、中斷處理程式

在I/O軟體中最底層的是中斷處理程式。當I/O裝置完成一次I/O操作時,裝置控制器會向中斷控制器發訊號,然後中斷控制器再向CPU發訊號,從而觸發一次中斷。

2.2、裝置驅動程式

裝置驅動程式是與具體的裝置型別密切相關的,用來控制裝置執行的程式。它一般是由生產廠商提供的。 在I/O軟體中,真正與I/O裝置密切相關的,直接對它們進行控制的軟體,就是裝置驅動程式。只有它才會去對裝置控制器中的暫存器進行操作,去讀狀態命令,去寫控制命令。 每一個I/O裝置都需要相應的裝置驅動程式,而每一個裝置驅動程式一般也只能處理一種型別的裝置。 裝置驅動程式在具體實現時,會執行一些步驟:
  • 初始化,如開啟裝置。
  • 解釋系統的命令,檢查輸入的引數是否有效。如果無效,則返回一個出錯的報告;如果有效,則把輸入的抽象引數轉換為控制裝置所需要的具體引數。
  • 檢查裝置當前是否空閒,如果裝置正忙,則這一次的操作請求暫時無法完成,因此把它加入到等待佇列,稍後再處理。如果空閒,再檢查硬體的狀態,看能夠開始執行。
  • 裝置驅動程式向裝置控制器發出一連串的命令,即把這些命令寫入到控制器的各個暫存器中,通過埠地址寫進去。
  • 當這個I/O操作完成以後,驅動程式會去檢查出錯的情況。如果一切正常,則程式執行結束,並返回一些狀態資訊給它的呼叫者。如果是一個輸入操作,那麼還要把輸入的資料上傳到上一層的系統軟體。

2.3、裝置獨立的I/O軟體(系統軟體)

在裝置驅動程式的上一層,是裝置獨立的I/O軟體,它是系統核心的一部分。 真正的I/O操作是由裝置驅動程式來完成的,而裝置驅動程式是由硬體廠商提供的,那麼對於作業系統的設計者來說,在系統的核心中,需要做以下幾個方面與I/O有關的事情:
  • 定義並實現與上層應用程式之間的一個統一介面
  • 定義並實現與裝置驅動程式的統一介面
  • 提供與裝置無關的資料塊大小
  • 緩衝技術
我們知道,在CPU和記憶體之間存在緩衝,這個緩衝位於CPU內部的快取記憶體Cache,即為了減少對記憶體的訪問次數,提高記憶體的訪問速度,可以把常用的一些資料儲存在Cache中。而在CPU和磁碟裝置之間也有緩衝,這個緩衝位於記憶體中,即為了減少對磁碟的訪問次數,提高磁碟的訪問速度,可以把常用的一些資料塊儲存在記憶體中。

2.4、使用者空間的I/O軟體

前面介紹的各種I/O軟體,都位於作業系統核心中,是作業系統的一部分。但也有另外一部分I/O軟體,並不在系統核心中。這主要有兩種:
  • 庫函式:與使用者程式進行連結的庫函式。
  • Spooling技術這是一種完全執行在使用者空間中的程式,它是在多道系統中,一種處理獨佔裝置的方法。
SPOOLing(Simultaneous  Peripheral Operation On Line)一般稱為假離線技術,或者虛擬裝置技術。它可以把一個獨佔裝置轉變為具有共享特徵的虛擬裝置,從而提高裝置的利用率。 它的基本思路是:在多道系統中,對於每一個獨佔的裝置,專門利用一道程式,即SPOOLing程式,來完成對這個裝置的輸入輸出操作。                                                                                 SPOOLing技術
具體來說:
  • 一方面,SPOOLing程式負責與這個獨佔的I/O裝置進行資料交換,這可以成為“實際的I/O”。如果這是一個輸入裝置,那麼SPOOLing程式預先從該裝置輸入資料並加以緩衝,然後在需要時再交給應用程式。如果這是一個輸出裝置,那麼SPOOLing程式會接受應用程式的輸出資料並加以緩衝,然後在適當的時候再輸出到該裝置。
  • 另一方面,應用程式在進行I/O操作時,只是與SPOOLing程式交換資料,這可以稱為“虛擬的I/O”。
SPOOLing技術的優點:
  • 高速的虛擬I/O操作:應用程式的虛擬I/O比實際的I/O速度要快,因為它只是在兩個程序之前的一種通訊,把資料從一個程序交給另一個程序。這種交換是在記憶體中進行的,而不是真正地讓機械的物理裝置去運作。這就縮短了應用程式的執行時間。
  • 實現對獨佔裝置的共享:由SPOOLing程式提供虛擬裝置,然後各個使用者程序就可以對這個獨佔裝置依次地共享使用。
例子: 印表機就是一種獨佔裝置,在任何時候只能允許一個使用者程序使用。在現代作業系統中,對於印表機裝置,普遍採用了SPOOLing技術。具體來說,首先建立一個SPOOLing程序,或稱後臺列印程式,以及一個SPOOLing目錄。當一個程序需要列印一個檔案時,首先會生成將要列印的檔案,並把它放入到SPOOLing目錄中,然後由這個後臺列印程序來負責真正的列印操作。