裝置與驅動的關係以及裝置號 裝置檔案

2021-08-01 17:01:53 字數 4922 閱讀 5827



linux裝置分類

linux下的裝置通常分為三類,字元裝置,塊裝置和網路裝置。

字元裝置

乙個字元裝置是一種位元組流裝置,對裝置的訪問只能按順序按位元組的訪問而不能隨機訪問,字元裝置沒有請求緩衝區,所有的訪問請求都是按順序執行的。linux下的大多裝置都是字元裝置。應用程式是通過字元裝置節點來訪問字元裝置的。裝置節點一般都由mknod命令都建立在/dev目錄下,下面的例子顯示了串列埠裝置的裝置節點。字元裝置檔案的第乙個標誌是前面的「c」標誌。

root#ls -l /dev/ttys[0-3]

crw-rw----  1 root  root 4, 64 feb 18 23:34 /dev/ttys0

crw-r-----  1 root  root 4, 65 nov 17 10:26 /dev/ttys1

crw-rw----  1 root  root 4, 66 jul  5  2000 /dev/ttys2

crw-rw----  1 root  root 4, 67 jul  5  2000 /dev/ttys3

字元裝置是指那些只能按順序乙個位元組乙個位元組讀取的裝置,但事實上現在一些高階字元裝置也可以從指定位置一次讀取一塊資料。字元裝置是面向資料流的裝置,每個字元裝置都有乙個裝置號,裝置號由主裝置號和次裝置號組成。同時linux使用管理檔案相同的方法來管理字元裝置,所以每個字元裝置在/dev/目錄下都有乙個對應的裝置檔案,即裝置節點,它們包含了裝置的型別、主/次裝置號以及裝置的訪問許可權控制等,系統通過裝置檔案來對字元裝置進行操作,每個字元裝置檔案都有自己的與普通檔案相同的檔案操作函式組結構(struct file_operations)。字元裝置驅動通常至少需要實現檔案操作函式組中的open、release、read和write四種操作方法。常見的字元裝置有滑鼠、鍵盤、串列埠、控制台等。

塊裝置

儲存裝置一般屬於塊裝置,塊裝置有請求緩衝區,並且支援隨機訪問而不必按照順序去訪問資料,比如你可以先訪問後面的資料,然後在訪問前面的資料,這對字元裝置來說是不可能的。linux下的磁碟裝置都是塊裝置,儘管在linux下有塊裝置節點,但應用程式一般是通過檔案系統及其快取記憶體來訪問塊裝置的,

而不是直接通過裝置節點來讀寫塊裝置上的資料。塊裝置檔案的第乙個標誌是前面的「b」標誌。

root#ls -l /dev/hda[1-3]

brw-rw----  1 root  root  3, 1 jul  5  2000 /dev/hda1

brw-rw----  1 root  root  3, 2 jul  5  2000 /dev/hda2

brw-rw----  1 root  root  3, 3 jul  5  2000 /dev/hda3

塊裝置是指那些可以從裝置的任意位置讀取任意長度資料的裝置。每個塊裝置同樣有乙個裝置號,裝置號由主裝置號和次裝置號組成。同時linux也使用管理檔案相同的方法來管理塊裝置,每個塊裝置在/dev/目錄下都有乙個對應的裝置檔案,即裝置節點,它們包含了裝置的型別、主/次裝置號以及裝置的訪問許可權控制等,系統通過裝置檔案來對塊裝置進行操作,每個塊裝置檔案都有自己的與普通檔案相同的檔案操作函式組結構(struct file_operations)。但塊裝置需要實現的操作方法遠比字元裝置的操作方法多得多,也難得多。塊裝置既可以作為普通的裸裝置用來存放任意資料,也可以將塊裝置按某種檔案系統型別的格式進行格式化,然後按照該檔案系統型別的格式來讀取塊裝置上的資料,但不管哪種方式,最後訪問裝置上的資料都必須通過呼叫裝置本身的操作方法實現,區別在於前者直接呼叫塊裝置的操作方法,而後者則間接呼叫塊裝置的操作方法。常見的塊裝置有各種硬碟、flash磁碟、ram磁碟等。

網路裝置

網路裝置不同於字元裝置和塊裝置,它是面向報文的而不是面向流的,它不支援隨機訪問,也沒有請求緩衝區。在linux裡乙個網路裝置也可以叫做乙個網路介面,如eth0,應用程式是通過socket而不是裝置節點來訪問網路裝置,在系統裡根本就不存在網路裝置節點。

網路介面用來與其他裝置交換資料,它可以是硬體裝置,也可以是純軟體裝置,如loopback介面就是乙個純軟體裝置。網路介面由核心中的網路子系統驅動,負責傳送和接收資料報,但它不需要了解每項事務如何對映到實際傳送的資料報,許多網路連線(尤其是使用tcp協議的連線)是面向流的,但網路裝置圍繞資料報的傳輸和接收設計。網路驅動程式不需要知道各個連線的相關資訊,它只需處理資料報。網路介面沒有像字元裝置和塊裝置一樣的裝置號,只有乙個唯一的名字,如eth0、eth1等,而這個名字也不需要與裝置檔案節點對應。核心使用一套與資料報傳輸相關的函式來與網路裝置驅動程式通訊,它們不同於字元裝置和塊裝置的read()和write()方法。

裝置節點、裝置驅動及裝置的關聯

當我們訪問乙個裝置節點是,系統是如果知道使用哪個裝置驅動及訪問哪個裝置的呢?這個是通過裝置號來實現的。當我們建立乙個裝置節點時需要指定主裝置號和次裝置號。對於裝置節點來說,名字不是重要的,裝置號才是最重要的,它實際指定了對應的驅動程式和對應的裝置。

linux的裝置管理是和檔案系統緊密結合的,各種裝置都以檔案的形式存放在/dev目錄下,稱為裝置檔案。應用程式可以開啟、關閉和讀寫這些裝置檔案,完成對裝置的操作,就像操作普通的資料檔案一樣。為了管理這些裝置,系統為裝置編了號,每個裝置號又分為主裝置號和次裝置號。主裝置號用來區分不同種類的裝置,而次裝置號用來區分同一型別的多個裝置。對於常用裝置,linux有約定俗成的編號,如硬碟的主裝置號是3。

linux為所有的裝置檔案都提供了統一的操作函式介面,方法是使用資料結構struct file_operations。這個資料結構中包括許多操作函式的指標,如open()、close()、read()和write()等,但由於外設的種類較多,操作方式各不相同。struct file_operations結構體中的成員為一系列的介面函式,如用於讀/寫的read/write函式和用於控制的ioctl等。開啟乙個檔案就是呼叫這個檔案file_operations中的open操作。不同型別的檔案有不同的file_operations成員函式,如普通的磁碟資料檔案,介面函式完成磁碟資料塊讀寫操作;而對於各種裝置檔案,則最終呼叫各自驅動程式中的i/o函式進行具體裝置的操作。這樣,應用程式根本不必考慮操作的是裝置還是普通檔案,可一律當作檔案處理,具有非常清晰統一的i/o介面。所以file_operations是檔案層次的i/o介面。

主裝置號

驅動程式在初始化時,會註冊它的驅動及對應主裝置號到系統中,這樣當應用程式訪問裝置節點時,系統就知道它所訪問的驅動程式了。你可以通過/proc/devices檔案來驅動系統裝置的主裝置號。

次裝置號

驅動程式遍歷裝置時,每發現乙個它能驅動的裝置,就建立乙個裝置物件,並為其分配乙個次裝置號以區分不同的裝置。這樣當應用程式訪問裝置節點時驅動程式就可以根據次裝置號知道它說訪問的裝置了。

系統中的每乙個字元裝置和塊裝置(網路介面沒有裝置號)都有乙個裝置號,傳統的unix以及早期版本linux中的裝置號是16位的,主次裝置號都是8位的,低8位為次裝置號,高8位為主裝置號,因此系統最多分別支援65536個字元裝置和65536個塊裝置,這個限制已經不能滿足當前層出不窮的各種新裝置的需要,所以linux2.6中對裝置號已經進行了擴充套件,乙個裝置號為32位,主裝置號為12位,次裝置號為20位,但是這32位裝置號的編碼方式有新舊兩種,舊的裝置編號格式為:最高12位為主裝置號,最低20位為次裝置號;新的裝置編號格式為:bit[19:8]是主裝置號,bit[31:20]是次裝置號的高12位,bit[7:0]是次裝置號的低8位。如果知道了乙個裝置的主裝置號major和次裝置號minor,那麼用mkdev(major,minor)生成是該裝置的舊格式的裝置號,用new_encode_dev(mkdev(major,minor))生成的則是新格式的裝置號。linux支援的各種裝置的主裝置號定義在include/linux/major.h檔案中,而已經在官方註冊的主裝置號和次裝置號在documentation/devices.txt檔案中可以找到。

老式16位裝置號、32位舊格式裝置號以及32位新格式裝置號的轉換操作函式如下:

new_encode_dev(dev_t dev)函式

將32位舊格式裝置號dev轉換成32位新格式裝置號。

new_decode_dev(u32 dev)函式

將32位新格式裝置號轉換成32位舊格式裝置號。

old_encode_dev(dev_t dev)函式

將32位舊格式裝置號轉換成老式16位裝置號。

dev_t old_decode_dev(u16 val)函式

將老式16位裝置號轉換成32位舊格式裝置號。

linux中裝置節點是通過「mknod」命令來建立的。乙個裝置節點其實就是乙個檔案,linux中稱為裝置檔案。有一點必要說明的是,在linux中,所有的裝置訪問都是通過檔案的方式,一般的資料檔案程式普通檔案,裝置節點稱為裝置檔案。在linux核心中網路裝置也是通過檔案操作的,稱為網路裝置檔案,在使用者空間是通過socket介面來訪問的。socket號就是網路裝置檔案描述符。

如:mknod /dev/mydevice c 254 0

(c代表子都裝置,254為主裝置號,0為次裝置號)

open,close等操作/dev/下裝置檔案,核心根據檔案的主裝置號找到對應的裝置驅動

主裝置號可以分為動態和靜態申請。

裝置檔案

linux使用對檔案一樣管理方式來管理裝置,所以對於系統中的每個字元裝置或者塊裝置都必須為其建立乙個裝置檔案,這個裝置檔案就是放在/dev/目錄下的裝置節點,它包含了該裝置的裝置型別(塊裝置或字元裝置)、裝置號(主裝置號和次裝置號)以及裝置訪問控制屬性等。裝置檔案可以通過手工用mknod命令生成也可以由udev使用者工具軟體在系統啟動後根據/sys目錄下每個裝置的實際資訊建立,使用後一種方式可以為每個裝置動態分配裝置號,而不必分配固定的裝置號,如果系統中的裝置不多,而且裝置型別又是常見的,可以使用手工方式生成裝置檔案,為常用裝置建立乙個已經分配號的裝置號對應的裝置檔案,這樣比較方便。如果系統很大,系統中的裝置太多,那麼最好動態分配裝置號,由udev在系統啟動之後根據裝置實際資訊自動建立裝置檔案。

字元裝置驅動 裝置號 裝置檔案

主裝置號用來標識與裝置檔案相連的驅動程式.用來反映裝置型別.次裝置號被驅動程式用來辨別操作的是哪乙個裝置.用來區分同型別的裝置.通過的是主裝置號.字元裝置檔案 本身沒有太多的內容,通過 字元裝置檔案 能找到 字元裝置驅動程式 字元裝置檔案 能將 應用程式 的需求傳遞給 字元裝置驅動程式.核心中如何描...

裝置驅動及Linux裝置號

在乙個計算機系統的開發過程中,應用層一般不會去關心底層硬體的具體操作,而是專注於應用層業務邏輯的實現,因此我們會將涉及到裝置硬體底層的操作封裝成乙個個介面,應用層在進行業務設計的過程中只需呼叫這些介面便可以完成想要的操作,這些介面我們可以成為裝置驅動。即使在乙個不執行作業系統的系統中 如傳統的51微...

字元裝置驅動與塊裝置驅動 網路裝置驅動的區別

在linux作業系統下有3類主要的裝置檔案型別 塊裝置 字元裝置和網路裝置。這種分類方法可以將控制輸入 輸出裝置的驅動程式與其他作業系統軟體分離開來。字元裝置是指訪問時沒有快取的裝置。典型的字元裝置包括滑鼠 鍵盤 序列口等。字元裝置與塊裝置的主要區別是 在對字元裝置發出讀 寫請求時,實際的硬體i o...