作者:Patrick Mochel
來源:網路
提要
sysfs是2.6核心的一個特性,它允許核心代碼經由一個in-memory的檔案系統把資訊出報(export)到使用者進程中,檔案系統的目錄層級(hierarchy)的組織是嚴格的,並構成了核心資料結構的內部組織的基礎。在這種檔案系統中產生的檔案大多數是ASCII檔案,通常每個檔案有一個值。這些特性保證了被出報的資訊的準確性並易於被訪問,從而使sysfs成為2.6核心的最直觀、最有用的特性之一。
介紹
sysfs是核心對象、屬性及它們的相互關係的一種表現機制。它提供了兩個組件:把這些條目通過sysfs來出報的核心編程介面,和一個使用者介面,用來查看和操作這些映射了它們所代表的核心對象的條目。下面這個表揭示了內部(核心)建制與他們的外部(使用者空間)sysfs映射。
內部----- 外部
核心對象---目錄
對象屬性---常規檔案
對象關係---符號串連
sysfs 是核心底層的一個核心成分,它的意義在於提供一個較為簡單的介面來實施一項簡單的任務,代碼中很少有過分複雜的內容或含混的描述。然而,像許多底層的核心成分一樣,它會有點抽象和疏離以致於難以縷清思路。為了減輕困難,在進入實質性的細節之前本文先對sysfs來一個漸進的詮釋。
首先寫一段短小精悍的曆史描述它的起源,其次是包括了對sysfs的掛載與訪問的關鍵資訊,而後傳述了sysfs中的目錄組織和子系統布局,它為使用者理解通過sysfs出報的資訊的組織與內容提供了足夠的資訊,儘管由於時間與篇幅的局限,不是每個對象及其屬性都會被寫到。
這篇文章的首要目的是為內部sysfs介面 - 用來把核心建制向使用者空間出報的資料結構與函數 - 提供一個技術視角,它描述了上面提到的三個概念(核心對象、對象屬性和對象關係)中的函數,並為每個概念設一個章節。它還為另外兩個用來簡化一些普通操作的常規檔案介面 - 屬性群組與二進位屬性 - 分別設一個章節。
sysfs是核心空間與使用者空間之間的一個資訊渠道,使用者空間的應用程式有很多機會來利用這種資訊,目前的利用法是I/O調度器的參數能力與udev程式。最末章節敘述了使用sysfs的當前應用的一個範例,並且為促使這個領域的進一步開發作一個鞭策。
因為它是個簡單的而且基本上是抽象的介面,所以需要很多時間來描述它與使用它的子系統們之間的互動。對於kobject與device model來說更是這樣,這兩個都是2.6核心的新特性並與sysfs密切地交織在一起,由於篇幅所限本文不可能對這些話題都充分地展開,還是把它們留給其它的文章作主題吧。
1. sysfs 的曆史
sysfs是一個in-memory檔案系統,最開始是基於ramfs的, ramfs是在2.4.0版核心穩定流程中的時候寫成的,它作得很妙,通過它可以看到利用當時還是新事物的VFS layer寫一個簡單的檔案系統是多麼地容易,由於它簡易並使用VFS,它成為一個好的基礎,使其它的in-memory檔案系統從它那裡衍生出來。
sysfs 最初被稱為ddfs(裝置驅動檔案系統),它的產生是為了調試正在開發過程中的新的驅動模型,調試代碼最初使用procfs來出報裝置樹,但在萊納斯*托瓦茲的嚴格的催促下,它轉而使用了一個基於ramfs的新的檔案系統。
當時,這種新的裝置模型被溶入核心(2.5.1前後),為了使其更明了給它換了個名字叫driverfs,次年在2.5版的開發中,這種裝置模型與裝置檔案系統的底層功能證明對其它的子系統很有用。kobject被開發出來,提供了一個中央對象管理機制,而裝置檔案系統則被轉換成sysfs,來表示它的子系統的不可預知性。
2. sysfs 的掛載
sysfs像其它基於記憶體的檔案系統一樣可以從使用者空間掛載:
mount -t sysfs sysfs /sys
sysfs還能夠在啟動時用/etc/fstab檔案來自動掛載。大多數支援2.6 核心的發行版都在 /etc/fstab有sysfs行:
sysfs /sys sysfs noauto 0 0
注意sysfs被掛載的目錄:/sys, 這是sysfs 佳載點的事實標準位置,各主流發行版都採用這個作法。
3.sysfs 的瀏覽
既然sysfs是由目錄、檔案、軟串連組成的集合,那麼就可以用簡單的 shell工具來瀏覽和操作,本人推薦用 tree(1)這個工具,它是核心對象底層的核心的開發過程中最得力的助手。
sysfs掛載點的頂層是一定數量的目錄,這些目錄代表了註冊了sysfs的主要的子系統。在本文撰寫之時, 這些目錄是:
/sys/
| - - block
| - - bus
| - - class
| - - device
| - - firmware
| - - module
| - - power
這些目錄是在子系統註冊kobject核心的系統啟動時刻產生的, 當它們被初始化以後, 它們開始搜尋在各自的目錄內註冊了的對象。對象註冊sysfs的方式以及目錄如何產生的將在後文解釋. 其間, 有興趣的話最好在這個sysfs層級中來一番審視, 下面敘述各子系統的含義以及它們的內容。
3.1 塊
"塊"目錄包含了在系統中發現的每個塊裝置的子目錄,每個塊裝置的目錄中是各種屬性,描述了方方面面,從裝置大小到映射的dev_t數值,有一個指向塊裝置所映射的物理裝置的軟串連(在物理裝置樹上,將在後文說到),還有一個目錄揭示了I/O調度器的介面,這個介面提供了一些資料,它們是關於裝置請求隊列和一些可調整的特性,使用者和管理員可以用它們來最佳化效能,包括用它們來動態改變I/O調度器。每個分區塊裝置表示為塊裝置的子目錄,這些目錄中包含了分區的唯讀屬性。
3.2 匯流排
"匯流排"目錄包含了在核心中註冊而得到支援(統一編譯或是通過模組來載入的)的每個物理匯流排類型的子目錄, 部分輸出如下:
bus/
| - - ide
| - - pci
| - - scsi
| - - usb
每個匯流排類型以兩個子目錄列出: devices 和 drivers , devices目錄包含了在整個系統中發現的每一個該匯流排類型的裝置的列表,這些列出的裝置實際上是在全域裝置樹中指向裝置目錄的符號串連。如:
| - - 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
| - - 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0
| - - 0000:01:00.0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0
| - - 0000:02:00.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.0
| - - 0000:02:00.1 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.1
| - - 0000:02:01.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:01.0
| - - 0000:02:02.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:02.0
drivers目錄包含了註冊該匯流排類型的每個驅動的目錄,每個驅動目錄中是允許查看和操作裝置參數的屬性,和指向該裝置所綁定的物理裝置(在全域裝置樹上)的軟串連。
3.3 類
"類“目錄包含了在核心中註冊了的每個裝置類的表示,一個裝置類描述了裝置的一個功能類型,如下:
class/
| - - graphics
| - - input
| - - net
| - - printer
| - - scsi_device
| - - sound
| - - tty
每個裝置類包含了每個分配並註冊了那個裝置類的類對象的子目錄,大多數裝置類對象的目錄包含了指向與那個類對象關聯的裝置和驅動目錄(分別在全域的裝置層級與匯流排層級)的軟串連,注意,在裝置與物理裝置之間不一定是1:1的映射,一個物理裝置也許包含多個類對象執行不同的邏輯功能。例如,一個物理滑鼠會映射一個核心滑鼠對象,也會映射一個泛”輸入事件“裝置,也許還會映射一個”輸入調試“裝置。每個類與類對象會包含各種屬性,它們陣列出參數來描述並控制那個類對象,內容與格式完全是類依賴的,並依賴於核心中所存的支援。
(待續)