Linux 裝置檔案分類
Linux 的一個重要特點就是將所有的裝置都當做檔案進行處理,這一類特殊檔案就是裝置檔案,它們可以使用前面提到的檔案、I/O 相關函式進行操作,這樣就大大方便了對裝置的處理。它通常在/dev 下面存在一個對應的邏輯裝置節點,這個節點以檔案的形式存在。
Linux系統的裝置檔案分為三類:塊裝置檔案、字元裝置檔案和網路裝置檔案。
· 塊裝置檔案通常指一些需要以塊(如512 位元組)的方式寫入的裝置,如IDE 硬碟、SCSI硬碟、光碟機等。
· 字元型裝置檔案通常指可以直接讀寫,沒有緩衝區的裝置,如並口、虛擬控制檯等。
· 網路裝置檔案通常是指網路裝置訪問的BSD socket介面,如網絡卡等。
裝置號
裝置號是一個數字,它是裝置的標誌。就如前面所述,一個裝置檔案(也就是裝置節點)可以通過mknod命令來建立,其中指定了主裝置號和次裝置號。主裝置號表明某一類裝置,一般對應著確定的驅動程式;次裝置號一般是用於區分標明不同屬性,例如不同的使用方法,不同的位置,不同的操作等,它標誌著某個具體的物理裝置。高位元組為主裝置號和底位元組為次裝置號。例如,在系統中的塊裝置IDE 硬碟的主裝置號是3,而多個IDE 硬碟及其各個分割槽分別賦予次裝置號1、2、3……
驅動層次結構
Linux 下的裝置驅動程式是核心的一部分,執行在核心模式,也就是說裝置驅動程式為核心提供了一個I/O 介面,使用者使用這個介面實現對裝置的操作。下面顯示了典型的Linux 輸入/輸出系統中各層次結構和功能。
Linux裝置驅動程式包含中斷處理程式和裝置服務子程式兩部分。裝置服務子程式包含了所有與裝置操作相關的處理程式碼。它從面向使用者程序的裝置檔案系統中接受使用者命令,並對裝置控制器執行操作。這樣,裝置驅動程式遮蔽了裝置的特殊性,使使用者可以像對待檔案一樣操作裝置。
裝置控制器需要獲得系統服務時有兩種方式:查詢和中斷。因為Linux 下的裝置驅動程式是核心的一部分,在裝置查詢期間系統不能執行其他程式碼,查詢方式的工作效率比較低,所以只有少數裝置如軟盤驅動程式採取這種方式,大多裝置以中斷方式向裝置驅動程式發出輸入/輸出請求。
裝置驅動程式與外界的介面
每種型別的驅動程式,不管是字元裝置還是塊裝置都為核心提供相同的呼叫介面,因此核心能以相同的方式處理不同的裝置。Linux 為每種不同型別的裝置驅動程式維護相應的資料結構,以便定義統一的介面並實現驅動程式的可裝載性和動態性。Linux 裝置驅動程式與外界的介面可以分為如下三個部分。
· 驅動程式與作業系統核心的介面:這是通過資料結構file_operations(來完成的。
· 驅動程式與系統引導的介面:這部分利用驅動程式對裝置進行初始化。
· 驅動程式與裝置的介面:這部分描述了驅動程式如何與裝置進行互動,這與具體裝置密切相關。
裝置驅動程式的特點
綜上所述,Linux中的裝置驅動程式有如下特點。
(1)核心程式碼:裝置驅動程式是核心的一部分,如果驅動程式出錯,則可能導致系統崩潰。
(2)核心介面:裝置驅動程式必須為核心或者其子系統提供一個標準介面。比如,一個終端驅動程式必須為核心提供一個檔案I/O 介面;一個SCSI裝置驅動程式應該為SCSI子系統提供一個SCSI裝置介面,同時SCSI子系統也必須為核心提供檔案的I/O 介面及緩衝區。
(3)核心機制和服務:裝置驅動程式使用一些標準的核心服務,如記憶體分配等。
(4)可裝載:大多數的Linux 作業系統裝置驅動程式都可以在需要時裝載進核心,在不需要時從核心中解除安裝。
(5)可設定:Linux 作業系統裝置驅動程式可以整合為核心的一部分,並可以根據需要把其中的某一部分整合到核心中,這隻需要在系統編譯時進行相應的設定即可。
(6)動態性:在系統啟動且各個裝置驅動程式初始化後,驅動程式將維護其控制的裝置。如果該裝置驅動程式控制的裝置不存在也不影響系統的執行,那麼此時的裝置驅動程式只是多佔用了一點系統記憶體罷了。
字元裝置驅動編寫流程
在上一節中已經提到,裝置驅動程式可以使用模組的方式動態載入到核心中去。載入模組的方式與以往的應用程式開發有很大的不同。以往在開發應用程式時都有一個main函式作為程式的入口點,而在驅動開發時卻沒有main 函式,模組在呼叫insmod 命令時被載入,此時的入口點是init_module函式,通常在該函式中完成裝置的註冊。同樣,模組在呼叫rmmod函式時被解除安裝,此時的入口點是cleanup_module函式,在該函式中完成裝置的解除安裝。在裝置完成註冊載入之後,使用者的應用程式就可以對該裝置進行一定的操作,如read、write等,而驅動程式就是用於實現這些操作,在使用者應用程式呼叫相應入口函式時執行相關的操作,init_module入口點函式則不需要完成其他如read、write之類功能。