Linux 核心裝置模型¶
Patrick Mochel <mochel@digitalimplant.org>
起草於 2002 年 8 月 26 日 更新於 2006 年 1 月 31 日
概述¶
Linux 核心驅動模型是對核心中以前使用的所有不同驅動模型的統一。它旨在透過將一組資料和操作整合到全域性可訪問的資料結構中來增強橋和裝置的特定於匯流排的驅動程式。
傳統的驅動模型為它們控制的裝置實現某種樹狀結構(有時只是一個列表)。不同的匯流排型別之間沒有任何統一性。
當前的驅動模型為描述匯流排和可以出現在匯流排下的裝置提供了一個通用的、統一的資料模型。 統一的匯流排模型包括所有匯流排都具有的一組通用屬性,以及一組通用回撥,例如匯流排探測期間的裝置發現、匯流排關閉、匯流排電源管理等。
通用的裝置和橋介面反映了現代計算機的目標:即實現無縫裝置“即插即用”、電源管理和熱插拔的能力。 特別是,英特爾和微軟規定的模型(即 ACPI)確保幾乎在 x86 相容系統上的幾乎任何總線上的每個裝置都可以在此範例內工作。 當然,並非每個匯流排都能夠支援所有此類操作,儘管大多數匯流排都支援這些操作中的大多數。
下游訪問¶
通用資料欄位已從各個匯流排層移動到通用資料結構中。 匯流排層仍然必須訪問這些欄位,有時裝置特定的驅動程式也必須訪問這些欄位。
鼓勵其他匯流排層執行與 PCI 層所做的事情。 struct pci_dev 現在看起來像這樣
struct pci_dev {
...
struct device dev; /* Generic device interface */
...
};
首先請注意,struct pci_dev 中的 struct device dev 是靜態分配的。 這意味著在裝置發現時只分配一次。
另請注意,struct device dev 不一定定義在 pci_dev 結構的前面。 這是為了讓人們在匯流排驅動程式和全域性驅動程式之間切換時考慮他們在做什麼,並避免兩者之間進行毫無意義和不正確的轉換。
PCI 匯流排層可以自由地訪問 struct device 的欄位。 它知道 struct pci_dev 的結構,並且應該知道 struct device 的結構。 已轉換為當前驅動模型的各個 PCI 裝置驅動程式通常不應該也不應該觸控 struct device 的欄位,除非有令人信服的理由這樣做。
上述抽象防止了過渡階段期間不必要的痛苦。 如果不是以這種方式完成,那麼當一個欄位被重新命名或刪除時,每個下游驅動程式都會崩潰。 另一方面,如果只有匯流排層(而不是裝置層)訪問 struct device,則只有匯流排層需要更改。
使用者介面¶
由於具有系統中所有裝置的完整分層檢視,因此將完整的分層檢視匯出到使用者空間變得相對容易。 這已經透過實現一個名為 sysfs 的專用虛擬檔案系統來實現。
幾乎所有主流 Linux 發行版都會自動掛載此檔案系統; 您可以在“mount”命令的輸出中看到以下一些變體
$ mount
...
none on /sys type sysfs (rw,noexec,nosuid,nodev)
...
$
sysfs 的自動掛載通常是透過 /etc/fstab 檔案中的類似以下條目來完成的
none /sys sysfs defaults 0 0
或者在基於 Debian 的系統的 /lib/init/fstab 檔案中類似的東西
none /sys sysfs nodev,noexec,nosuid 0 0
如果 sysfs 沒有自動掛載,您始終可以使用以下命令手動掛載它
# mount -t sysfs sysfs /sys
每當裝置插入樹中時,都會為其建立一個目錄。 可以在發現的每一層(全域性層、匯流排層或裝置層)填充此目錄。
全域性層當前建立兩個檔案 - “name”和“power”。 前者僅報告裝置的名稱。 後者報告裝置的當前電源狀態。 它也將用於設定當前的電源狀態。
匯流排層還可以為其在探測匯流排時找到的裝置建立檔案。 例如,PCI 層當前為每個 PCI 裝置建立“irq”和“resource”檔案。
特定於裝置的驅動程式也可以在其目錄中匯出檔案,以公開特定於裝置的資料或可調介面。
有關 sysfs 目錄佈局的更多資訊,請參見此目錄中的其他文件和檔案 sysfs - 用於匯出核心物件的 _The_ 檔案系統。