裝置驅動程式與核心模組

主編號與次編號(major and minor number)

當程式開啟 /dev/sda 或 /dev/ttyS1 時,那個檔名只是給人看的標籤。核心需要一種數字方式來得知是哪個驅動程式擁有這個裝置、又是哪個特定實例。這正是主編號與次編號的用途:蓋在每個裝置節點上的兩部分數字識別碼。主編號說「哪個驅動程式」,次編號說「該驅動程式處理的哪個裝置」。

想像一棟大樓的樓層指示牌:主編號是部門(比如「序列埠驅動程式」),次編號是其中特定的辦公室(序列埠 0、序列埠 1、序列埠 2)。當一個裝置節點被建立時,它帶著這一對編號,包進一個叫 dev_t 的單一值裡。當你開啟節點時,核心讀取主編號以在它的表中查出已註冊的驅動程式,再把次編號傳給該驅動程式,讓它能分辨自己的各個裝置——一個序列埠驅動程式可能處理八個埠,每個是不同的次編號。驅動程式註冊時會宣告一段這樣的編號(過去用固定主編號;現代驅動程式通常用 alloc_chrdev_region 請核心動態配置一個)。

這些編號之所以重要,是因為它們才是 /dev 裡的名字與核心中程式碼之間真正的連結——節點的名字只是表面,編號才是承重的。一個常見混淆:檔名不必符合任何東西;你可以建立一個叫 /dev/banana、帶著正確主次編號的節點,它仍會抵達序列埠驅動程式。重要的是編號,不是名字。你可以用 ls -l /dev 看到它們,它們出現在檔案大小的位置。

$ ls -l /dev/ttyS0 /dev/sda crw-rw---- 1 root tty 4, 64 ... /dev/ttyS0 # 字元,主編號 4 次編號 64 brw-rw---- 1 root disk 8, 0 ... /dev/sda # 區塊,主編號 8 次編號 0 // 開頭的 c = 字元裝置,b = 區塊裝置

這兩個編號在 ls -l 中取代了檔案大小的位置;開頭的 c/b 標示字元或區塊。

節點的檔名只是表面;只有主/次編號會路由到驅動程式。現代驅動程式通常請求動態配置的主編號,而非寫死一個,以避免衝突。

又称
device numbersdev_t裝置編號