1.3. 設(shè)備和模塊的分類

2018-02-24 15:49 更新

1.3.?設(shè)備和模塊的分類

以 LInux 的方式看待設(shè)備可區(qū)分為 3 種基本設(shè)備類型. 每個(gè)模塊常常實(shí)現(xiàn) 3 種類型中的 1 種, 因此可分類成字符模塊, 塊模塊, 或者一個(gè)網(wǎng)絡(luò)模塊. 這種將模塊分成不同類型或類別的方法并非是固定不變的; 程序員可以選擇建立在一個(gè)大塊代碼中實(shí)現(xiàn)了不同驅(qū)動(dòng)的巨大模塊. 但是, 好的程序員, 常常創(chuàng)建一個(gè)不同的模塊給每個(gè)它們實(shí)現(xiàn)的新功能, 因?yàn)榉纸馐强缮炜s性和可擴(kuò)張性的關(guān)鍵因素.

3 類驅(qū)動(dòng)如下:

既然不是一個(gè)面向流的設(shè)備, 一個(gè)網(wǎng)絡(luò)接口就不象 /dev/tty1 那么容易映射到文件系統(tǒng)的一個(gè)結(jié)點(diǎn)上. Unix 的提供對接口的存取的方式仍然是通過分配一個(gè)名子給它們( 例如 eth0 ), 但是這個(gè)名子在文件系統(tǒng)中沒有對應(yīng)的入口. 內(nèi)核與網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)間的通訊與字符和塊設(shè)備驅(qū)動(dòng)所用的完全不同. 不用 read 和 write, 內(nèi)核調(diào)用和報(bào)文傳遞相關(guān)的函數(shù).

字符設(shè)備
一個(gè)字符( char ) 設(shè)備是一種可以當(dāng)作一個(gè)字節(jié)流來存取的設(shè)備( 如同一個(gè)文件 ); 一個(gè)字符驅(qū)動(dòng)負(fù)責(zé)實(shí)現(xiàn)這種行為. 這樣的驅(qū)動(dòng)常常至少實(shí)現(xiàn) open, close, read, 和 write 系統(tǒng)調(diào)用. 文本控制臺( /dev/console )和串口( /dev/ttyS0 及其友 )是字符設(shè)備的例子, 因?yàn)樗鼈兒芎玫卣宫F(xiàn)了流的抽象. 字符設(shè)備通過文件系統(tǒng)結(jié)點(diǎn)來存取, 例如 /dev/tty1 和 /dev/lp0. 在一個(gè)字符設(shè)備和一個(gè)普通文件之間唯一有關(guān)的不同就是, 你經(jīng)??梢栽谄胀ㄎ募幸苼硪迫? 但是大部分字符設(shè)備僅僅是數(shù)據(jù)通道, 你只能順序存取.然而, 存在看起來象數(shù)據(jù)區(qū)的字符設(shè)備, 你可以在里面移來移去. 例如, frame grabber 經(jīng)常這樣, 應(yīng)用程序可以使用 mmap 或者 lseek 存取整個(gè)要求的圖像.

塊設(shè)備
如同字符設(shè)備, 塊設(shè)備通過位于 /dev 目錄的文件系統(tǒng)結(jié)點(diǎn)來存取. 一個(gè)塊設(shè)備(例如一個(gè)磁盤)應(yīng)該是可以駐有一個(gè)文件系統(tǒng)的. 在大部分的 Unix 系統(tǒng), 一個(gè)塊設(shè)備只能處理這樣的 I/O 操作, 傳送一個(gè)或多個(gè)長度經(jīng)常是 512 字節(jié)( 或一個(gè)更大的 2 的冪的數(shù) )的整塊. Linux, 相反, 允許應(yīng)用程序讀寫一個(gè)塊設(shè)備象一個(gè)字符設(shè)備一樣 -- 它允許一次傳送任意數(shù)目的字節(jié). 結(jié)果就是, 塊和字符設(shè)備的區(qū)別僅僅在內(nèi)核在內(nèi)部管理數(shù)據(jù)的方式上, 并且因此在內(nèi)核/驅(qū)動(dòng)的軟件接口上不同. 如同一個(gè)字符設(shè)備, 每個(gè)塊設(shè)備都通過一個(gè)文件系統(tǒng)結(jié)點(diǎn)被存取的, 它們之間的區(qū)別對用戶是透明的. 塊驅(qū)動(dòng)和字符驅(qū)動(dòng)相比, 與內(nèi)核的接口完全不同.

網(wǎng)絡(luò)接口
任何網(wǎng)絡(luò)事務(wù)都通過一個(gè)接口來進(jìn)行, 就是說, 一個(gè)能夠與其他主機(jī)交換數(shù)據(jù)的設(shè)備. 通常, 一個(gè)接口是一個(gè)硬件設(shè)備, 但是它也可能是一個(gè)純粹的軟件設(shè)備, 比如環(huán)回接口. 一個(gè)網(wǎng)絡(luò)接口負(fù)責(zé)發(fā)送和接收數(shù)據(jù)報(bào)文, 在內(nèi)核網(wǎng)絡(luò)子系統(tǒng)的驅(qū)動(dòng)下, 不必知道單個(gè)事務(wù)是如何映射到實(shí)際的被發(fā)送的報(bào)文上的. 很多網(wǎng)絡(luò)連接( 特別那些使用 TCP 的)是面向流的, 但是網(wǎng)絡(luò)設(shè)備卻常常設(shè)計(jì)成處理報(bào)文的發(fā)送和接收. 一個(gè)網(wǎng)絡(luò)驅(qū)動(dòng)對單個(gè)連接一無所知; 它只處理報(bào)文.

有其他的劃分驅(qū)動(dòng)模塊的方式, 與上面的設(shè)備類型是正交的. 通常, 某些類型的驅(qū)動(dòng)與給定類型設(shè)備的其他層的內(nèi)核支持函數(shù)一起工作. 例如, 你可以說 USB 模塊, 串口模塊, SCSI 模塊, 等等. 每個(gè) USB 設(shè)備由一個(gè) USB 模塊驅(qū)動(dòng), 與 USB 子系統(tǒng)一起工作, 但是設(shè)備自身在系統(tǒng)中表現(xiàn)為一個(gè)字符設(shè)備( 比如一個(gè) USB 串口 ), 一個(gè)塊設(shè)備( 一個(gè) USB 內(nèi)存讀卡器 ), 或者一個(gè)網(wǎng)絡(luò)設(shè)備( 一個(gè) USB 以太網(wǎng)接口 ).

另外的設(shè)備驅(qū)動(dòng)類別近來已經(jīng)添加到內(nèi)核中, 包括 FireWire 驅(qū)動(dòng)和 I2O 驅(qū)動(dòng). 以它們處理 USB 和 SCSI 驅(qū)動(dòng)相同的方式, 內(nèi)核開發(fā)者集合了類別范圍內(nèi)的特性, 并把它們輸出給驅(qū)動(dòng)實(shí)現(xiàn)者, 以避免重復(fù)工作和 bug, 因此簡化和加強(qiáng)了編寫類似驅(qū)動(dòng)的過程.

在設(shè)備驅(qū)動(dòng)之外, 別的功能, 不論硬件和軟件, 在內(nèi)核中都是模塊化的. 一個(gè)普通的例子是文件系統(tǒng). 一個(gè)文件系統(tǒng)類型決定了在塊設(shè)備上信息是如何組織的, 以便能表示一棵目錄與文件的樹. 這樣的實(shí)體不是設(shè)備驅(qū)動(dòng), 因?yàn)闆]有明確的設(shè)備與信息擺放方式相聯(lián)系; 文件系統(tǒng)類型卻是一種軟件驅(qū)動(dòng), 因?yàn)樗鼘⒌图墧?shù)據(jù)結(jié)構(gòu)映射為高級的數(shù)據(jù)結(jié)構(gòu). 文件系統(tǒng)決定一個(gè)文件名多長, 以及在一個(gè)目錄入口中存儲每個(gè)文件的什么信息. 文件系統(tǒng)模塊必須實(shí)現(xiàn)最低級的系統(tǒng)調(diào)用, 來存取目錄和文件, 通過映射文件名和路徑( 以及其他信息, 例如存取模式 )到保存在數(shù)據(jù)塊中的數(shù)據(jù)結(jié)構(gòu). 這樣的一個(gè)接口是完全與數(shù)據(jù)被傳送來去磁盤( 或其他介質(zhì) )相互獨(dú)立, 這個(gè)傳送是由一個(gè)塊設(shè)備驅(qū)動(dòng)完成的.

如果你考慮一個(gè) Unix 系統(tǒng)是多么依賴下面的文件系統(tǒng), 你會認(rèn)識到這樣的一個(gè)軟件概念對系統(tǒng)操作是至關(guān)重要的. 解碼文件系統(tǒng)信息的能力處于內(nèi)核層級中最低級, 并且是最重要的; 甚至如果你為你的新 CD-ROM 編寫塊驅(qū)動(dòng), 如果你對上面的數(shù)據(jù)不能運(yùn)行 ls 或者 cp 就毫無用處. Linux 支持一個(gè)文件系統(tǒng)模塊的概念, 其軟件接口聲明了不同操作, 可以在一個(gè)文件系統(tǒng)節(jié)點(diǎn), 目錄, 文件和超級塊上進(jìn)行操作. 對一個(gè)程序員來說, 居然需要編寫一個(gè)文件系統(tǒng)模塊是非常不常見的, 因?yàn)楣俜絻?nèi)核已經(jīng)包含了大部分重要的文件系統(tǒng)類型的代碼.

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號