裝置節點(device node)
Linux 以「幾乎一切皆檔案」著稱,硬體也包含在內。但磁碟其實不是磁碟上的一個檔案——那你要怎麼 open() 它?裝置節點是檔案系統中一個特殊的項目,通常位於 /dev 底下,看起來像檔案,實際上是通往某裝置的把手。開啟它不會從檔案系統讀出任何位元組;它反而把你的檔案描述符連到核心中的某個驅動程式。
裝置節點由一個系統呼叫(mknod,或由裝置管理員自動)建立,並在它的索引節點裡儲存三樣東西:它是字元還是區塊裝置,以及主編號與次編號。它本身不持有任何資料。當程式呼叫 open("/dev/mychar", ...) 時,核心看到這個索引節點是裝置節點,讀取主編號找到正確的驅動程式、讀取次編號挑出裝置,並把產生的檔案描述符接到該驅動程式的 file_operations。從那時起,對該描述符的 read() 與 write() 都直接通往驅動程式的處理常式。在現代系統上你很少親手做節點:一個使用者空間常駐程式(udev)監看核心,並在裝置出現時自動在 /dev 中建立節點,通常透過一個暫時的檔案系統(devtmpfs)。
裝置節點之所以重要,是因為它是讓普通檔案 API 與普通權限位元控制硬體的橋樑:對節點下 chmod 與 chown 就決定誰能使用該裝置。一個澄清:節點只是一個名字加上一個(型別、主編號、次編號)三元組——它不含驅動程式碼,也不存裝置資料。刪除節點不會卸載驅動程式,而為一個沒有驅動程式宣告的主編號建立節點,你會得到一個無法成功開啟的節點。
$ sudo mknod /dev/mychar c 240 0 # 型別 c、主編號 240、次編號 0 $ ls -l /dev/mychar crw-r--r-- 1 root root 240, 0 ... /dev/mychar # 現在 open("/dev/mychar") 會抵達宣告了主編號 240 的驅動程式
mknod 建立一個帶著(型別、主編號、次編號)三元組的節點;開啟它會路由到宣告了那個主編號的驅動程式。
裝置節點不存資料也不存程式碼——只有一個(型別、主編號、次編號)三元組。在現代系統上,udev/devtmpfs 會自動建立節點;為一個無人宣告的主編號親手做的節點只會開啟失敗。