sysfs 文件系統

 

sysfs 文件系統總是被掛載在 /sys 掛載點上。雖然在較早期的2.6內核系統上並沒有規定 sysfs 的標準掛載位置,可以把 sysfs 掛載在任何位置,但較近的2.6內核修正了這一規則,要求 sysfs 總是掛載在 /sys 目錄上;針對以前的 sysfs 掛載位置不固定或沒有標準被掛載,有些程序從 /proc/mounts 中解析出 sysfs 是否被掛載以及具體的掛載點,這個步驟現在已經不需要了。請參考附錄給出的 sysfs-rules.txt 文件鏈接。

sysfs 與 proc

sysfs 與 proc 相比有很多優點,最重要的莫過於設計上的清晰。一個 proc 虛擬文件可能有內部格式,如 /proc/scsi/scsi ,它是可讀可寫的,(其文件權限被錯誤地標記爲了 0444 !,這是內核的一個BUG),並且讀寫格式不一樣,代表不同的操作,應用程序中讀到了這個文件的內容一般還需要進行字符串解析,而在寫入時需要先用字符串 格式化按指定的格式寫入字符串進行操作;相比而言, sysfs 的設計原則是一個屬性文件只做一件事情, sysfs 屬性文件一般只有一個值,直接讀取或寫入。整個 /proc/scsi 目錄在2.6內核中已被標記爲過時(LEGACY),它的功能已經被相應的 /sys 屬性文件所完全取代。新設計的內核機制應該儘量使用 sysfs 機制,而將 proc 保留給純淨的“進程文件系統”。

 

初識 /sys


清單 1. 與 /sys 文件系統的一次交互(視內核版本號和外接設備的不同,在您的系統上執行這些命令的結果可能與此有所不同)

$ ls -F /sys
block/ bus/ class/ dev/ devices/ firmware/ fs/ kernel/ module/ power/
$ ls -F /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/
broken_parity_status enable modalias resource0 rom uevent
class irq msi_bus resource0_wc subsystem@ vendor
config local_cpulist power/ resource1 subsystem_device
device local_cpus resource resource2 subsystem_vendor

這是在 Fedora 10 的 2.6.27.5-117.fc10.i686 的內核上,可以看到在 /sys 目錄下有 block, bus, class, dev, devices, firmware, fs, kernel, module, power 這些子目錄,本文將分別介紹這些目錄存在的含義。

第二個 ls 命令展示了在一個 pci 設備目錄下的文件, "ls" 命令的 "-F" 命令爲所列出的每個文件使用後綴來顯示文件的類型,後綴 "/" 表示列出的是目錄,後綴 "@" 表示列出的是符號鏈接文件。可以看到第二個目錄下包含有普通文件 (regular file) 和符號鏈接文件 (symbolic link file) ,本文也將以這個具體的設備爲例說明其中每一個普通文件的用途。

/sys 文件系統下的目錄結構

/sys 下的目錄結構是經過精心設計的:在 /sys/devices 下是所有設備的真實對象,包括如視頻卡和以太網卡等真實的設備,也包括 ACPI 等不那麼顯而易見的真實設備、還有 tty, bonding 等純粹虛擬的設備;在其它目錄如 class, bus 等中則在分類的目錄中含有大量對 devices 中真實對象引用的符號鏈接文件; 清單1 中在 /sys 根目錄下頂層目錄的意義如下:


表 1. /sys 下的目錄結構

/sys 下的子目錄所包含的內容
/sys/devices 這是內核對系統中所有設備的分層次表達模型,也是 /sys 文件系統管理設備的最重要的目錄結構,下文會對它的內部結構作進一步分析;
/sys/dev 這個目錄下維護一個按字符設備和塊設備的主次號碼(major:minor)鏈接到真實的設備(/sys/devices下)的符號鏈接文件,它是在內核 2.6.26 首次引入;
/sys/bus 這是內核設備按總線類型分層放置的目錄結構, devices 中的所有設備都是連接於某種總線之下,在這裏的每一種具體總線之下可以找到每一個具體設備的符號鏈接,它也是構成 Linux 統一設備模型的一部分;
/sys/class 這是按照設備功能分類的設備模型,如系統所有輸入設備都會出現在 /sys/class/input 之下,而不論它們是以何種總線連接到系統。它也是構成 Linux 統一設備模型的一部分;
/sys/block 這裏是系統中當前所有的塊設備所在,按照功能來說放置在 /sys/class 之下會更合適,但只是由於歷史遺留因素而一直存在於 /sys/block, 但從 2.6.22 開始就已標記爲過時,只有在打開了 CONFIG_SYSFS_DEPRECATED 配置下編譯纔會有這個目錄的存在,並且在 2.6.26 內核中已正式移到 /sys/class/block, 舊的接口 /sys/block 爲了向後兼容保留存在,但其中的內容已經變爲指向它們在 /sys/devices/ 中真實設備的符號鏈接文件;
/sys/firmware 這裏是系統加載固件機制的對用戶空間的接口,關於固件有專用於固件加載的一套API,在附錄 LDD3 一書中有關於內核支持固件加載機制的更詳細的介紹;
/sys/fs 這裏按照設計是用於描述系統中所有文件系統,包括文件系統本身和按文件系統分類存放的已掛載點,但目前只有 fuse,gfs2 等少數文件系統支持 sysfs 接口,一些傳統的虛擬文件系統(VFS)層次控制參數仍然在 sysctl (/proc/sys/fs) 接口中中;
/sys/kernel 這裏是內核所有可調整參數的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等幾項較新的設計在使用它,其它內核可調整參數仍然位於 sysctl (/proc/sys/kernel) 接口中 ;
/sys/module 這裏有系統中所有模塊的信息,不論這些模塊是以內聯(inlined)方式編譯到內核映像文件(vmlinuz)中還是編譯爲外部模塊(ko文件),都可能會出現在 /sys/module 中:
  • 編譯爲外部模塊(ko文件)在加載後會出現對應的 /sys/module/<module_name>/, 並且在這個目錄下會出現一些屬性文件和屬性目錄來表示此外部模塊的一些信息,如版本號、加載狀態、所提供的驅動程序等;
  • 編譯爲內聯方式的模塊則只在當它有非0屬性的模塊參數時會出現對應的 /sys/module/<module_name>, 這些模塊的可用參數會出現在 /sys/modules/<modname>/parameters/<param_name> 中,
    • 如 /sys/module/printk/parameters/time 這個可讀寫參數控制着內聯模塊 printk 在打印內核消息時是否加上時間前綴;
    • 所有內聯模塊的參數也可以由 "<module_name>.<param_name>=<value>" 的形式寫在內核啓動參數上,如啓動內核時加上參數 "printk.time=1" 與 向 "/sys/module/printk/parameters/time" 寫入1的效果相同;
  • 沒有非0屬性參數的內聯模塊不會出現於此。
/sys/power 這裏是系統中電源選項,這個目錄下有幾個屬性文件可以用於控制整個機器的電源狀態,如可以向其中寫入控制命令讓機器關機、重啓等。
/sys/slab (對應 2.6.23 內核,在 2.6.24 以後移至 /sys/kernel/slab) 從2.6.23 開始可以選擇 SLAB 內存分配器的實現,並且新的 SLUB(Unqueued Slab Allocator)被設置爲缺省值;如果編譯了此選項,在 /sys 下就會出現 /sys/slab ,裏面有每一個 kmem_cache 結構體的可調整參數。對應於舊的 SLAB 內存分配器下的 /proc/slabinfo 動態調整接口,新式的 /sys/kernel/slab/<slab_name> 接口中的各項信息和可調整項顯得更爲清晰。

接下來對 /sys/devices/ 下的目錄結構作進一步探討:


清單 2. 查看 /sys/devices/ 的目錄結構

$ ls -F /sys/devices/
isa/ LNXSYSTM:00/ pci0000:00/ platform/ pnp0/ pnp1/ system/ virtual/

可以看到,在 /sys/devices/ 目錄下是按照設備的基本總線類型分類的目錄,再進入進去查看其中的 PCI 類型的設備:


清單 3. 查看 /sys/devices/pci0000:00/ 的目錄結構

$ ls -F /sys/devices/pci0000:00/
0000:00:00.0/ 0000:00:02.5/ 0000:00:03.1/ 0000:00:0e.0/ power/
0000:00:01.0/ 0000:00:02.7/ 0000:00:03.2/ firmware_node@ uevent
0000:00:02.0/ 0000:00:03.0/ 0000:00:03.3/ pci_bus/

在 /sys/devices/pci0000:00/ 目錄下是按照 PCI 總線接入的設備號分類存放的目錄,再查看其中一個,


清單 4. 查看 /sys/devices/pci0000:00/ 的目錄結構

$ ls -F /sys/devices/pci0000:00/0000:00:01.0/
0000:01:00.0/ device local_cpus power/ subsystem_vendor
broken_parity_status enable modalias resource uevent
class irq msi_bus subsystem@ vendor
config local_cpulist pci_bus/ subsystem_device

可以看到,其中有一個目錄 0000:01:00.0/, 其它都是屬性文件和屬性組,而如果對 0000:01:00.0/ 子目錄中進行再列表查看則會得到 清單1 的目錄結構。

繼續以上過程可以瞭解整個目錄樹的結構,這裏把它整理成 圖 1. sysfs 目錄層次圖

 

 

其中涉及到 ksets, kobjects, attrs 等很多術語,這就不得不提到 Linux 統一設備模型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章