簡單介紹Linux sysfs 桌面操作系統(tǒng)
本人對Linux系統(tǒng)很感興趣,常見Linux sysfs 屬性的功能Linux本身是這個操作系統(tǒng)的核心部分,也就是操作系統(tǒng)的內(nèi)核。內(nèi)核是完成那些最基本操作的程序,它負(fù)責(zé)其他程序(如文本編輯器程序)的啟動與終止、內(nèi)存申請?zhí)幚碛脖P訪問、網(wǎng)絡(luò)連接管理等方面的工作。
使用 Linux sysfs 的關(guān)鍵就是掌握這些 sysfs 屬性的用法,下面以一些常見的 sysfs 屬性來展示它的用法;
使用設(shè)備(PCI)的 sysfs 屬性文件以一份桌面系統(tǒng)上的視頻卡為例,列舉它對應(yīng)的 kobject 上的屬性文件的對應(yīng)用途;一般來說,在 Linux 桌面上都有視頻卡以支持 Xorg 軟件包作為 XWindow 服務(wù)器來運行,因此先找到 Xorg 的進程號,查看這個進程所使用的所有文件(注意查看這個進程屬性需要 root 用戶權(quán)限);
# ps xfa |grep Xorg
2001 tty1 Ss+ 2:24 \_ /usr/bin/Xorg :0 -nr -verbose -auth \
/var/run/gdm/auth-for-gdm-NPrkZK/database -nolisten tcp vt1
# lsof -nP -p 2001
Xorg 2001 root mem REG 8,3 617732 231033 \
/usr/lib/xorg/modules/drivers/sis_drv.so
[...]
Xorg 2001 root mem REG 0,0 134217728 5529 \
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource0
Xorg 2001 root mem REG 0,0 131072 5531 \
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource1
[...]
Xorg 2001 root 7u REG 0,0 256 5504 \
/sys/devices/pci0000:00/0000:00:00.0/config
Xorg 2001 root 8u unix 0xdbe66000 0t0 8756 socket
Xorg 2001 root 9u REG 0,0 256 5528 \
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/config
注意到此 Xorg 服務(wù)器是以內(nèi)存映射 (mem) 的形式打開了 "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource0" 和 "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource1" ,同時以文件讀寫形式 (7u,9u) 打開了 "/sys/devices/pci0000:00/0000:00:00.0/config" 和 "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/config"
事實上, PCI 設(shè)備對應(yīng)的 kobject 目錄下的 config 正是代表PCI設(shè)備的“配置空間”,對于普通 PCI (非PCI-E)設(shè)備而言,其配置空間大小一般是 256字節(jié),這個空間可以使用十六進制工具 dump 出來,如下。(有關(guān) PCI 設(shè)備本身的三種地址空間,請參考附錄 LDD3)
# hexdump -C /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/config
00000000 39 10 30 63 03 00 30 02 00 00 00 03 00 00 00 80 |9.0c..0.........|
00000010 08 00 00 d8 00 00 00 e1 01 d0 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 19 10 30 1b |..............0.|
00000030 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
00000040 01 50 02 06 00 00 00 00 00 00 00 00 00 00 00 00 |.P..............|
00000050 02 00 30 00 0b 02 00 ff 00 00 00 00 00 00 00 00 |..0.............|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100
這個空間正好是 256字節(jié)大小,熟悉 PCI 的人們還可以知道,從 PCI 配置空間可以讀到有關(guān)此 PCI 設(shè)備的很多有用信息,如廠商代碼,設(shè)備代碼,IRQ 號碼等;前四個字節(jié) 0x39 0x10 0x30 0x63 就是按小端(little endian)存放的2個短整數(shù),因此其 PCI 廠商號碼和 PCI 設(shè)備號碼分別是 0x1039 和 0x6330
# lspci -v -d 1039:6330
01:00.0 VGA compatible controller: Silicon Integrated Systems [SiS] 661/741/760 PCI/AGP \
or 662/761Gx PCIE VGA Display Adapter (prog-if 00 [VGA controller])
Subsystem: Elitegroup Computer Systems Device 1b30
Flags: 66MHz, medium devsel
BIST result: 00
Memory at d8000000 (32-bit, prefetchable) [size=128M]
Memory at e1000000 (32-bit, non-prefetchable) [size=128K]
I/O ports at d000 [size=128]
Capabilities: [40] Power Management version 2
Capabilities: [50] AGP version 3.0
在 PCI 設(shè)備上除了有 config 是配置空間對用戶的接口以外,還有 resource{0,1,2,...} 是資源空間,對應(yīng)著 PCI 設(shè)備的可映射內(nèi)存空間;此外 PCI 設(shè)備還提供了很多接口,全部列表如下:
# ls -lU /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/
總計 0
-rw-r--r-- 1 root root 4096 12-09 00:28 uevent
-r--r--r-- 1 root root 4096 12-09 00:27 resource
-r--r--r-- 1 root root 4096 12-09 00:27 vendor
-r--r--r-- 1 root root 4096 12-09 00:27 device
-r--r--r-- 1 root root 4096 12-09 00:28 subsystem_vendor
-r--r--r-- 1 root root 4096 12-09 00:28 subsystem_device
-r--r--r-- 1 root root 4096 12-09 00:27 class
-r--r--r-- 1 root root 4096 12-09 00:27 irq
-r--r--r-- 1 root root 4096 12-09 00:28 local_cpus
-r--r--r-- 1 root root 4096 12-09 00:28 local_cpulist
-r--r--r-- 1 root root 4096 12-09 00:28 modalias
-rw------- 1 root root 4096 12-09 00:28 enable
-rw-r--r-- 1 root root 4096 12-09 00:28 broken_parity_status
-rw-r--r-- 1 root root 4096 12-09 00:28 msi_bus
lrwxrwxrwx 1 root root 0 12-09 00:28 subsystem -> ../../../../bus/pci
drwxr-xr-x 2 root root 0 12-09 00:28 power
-rw-r--r-- 1 root root 256 12-08 23:03 config
-rw------- 1 root root 134217728 12-08 23:03 resource0
-rw------- 1 root root 134217728 12-09 00:28 resource0_wc
-rw------- 1 root root 131072 12-08 23:03 resource1
-rw------- 1 root root 128 12-09 00:28 resource2
-r-------- 1 root root 0 12-09 00:28 rom
可以看到很多其它屬性文件,這些屬性文件的權(quán)限位也都是正確的,有 w 權(quán)限位的才是可以寫入。其中大小為 4096字節(jié)的屬性一般是純文本描述的屬性,可以直接 cat 讀出和用 echo 字符串的方法寫入;其它非 4096字節(jié)大小的一般是二進制屬性,類似于上面的 config 屬性文件;關(guān)于純文本屬性和二進制屬性,在下文 編程實踐:添加Linux sysfs支持 一節(jié)會進一步說明。
從 vendor, device, subsystem_vendor, subsystem_device, class, resource 這些只讀屬性上分別可以讀到此 PCI 設(shè)備的廠商號、設(shè)備號、子系統(tǒng)廠商號、子系統(tǒng)設(shè)備號、PCI類別、資源表等,這些都是相應(yīng) PCI 設(shè)備的屬性,其實就是直接從 config 二進制文件讀出來,按照配置空間的格式讀出這些號碼;
使用 enable 這個可寫屬性可以禁用或啟用這個 PCI 設(shè)備,設(shè)備的過程很直觀,寫入1代表啟用,寫入0則代表禁用;
subsystem 和 driver 符號鏈接文件分別指向?qū)?yīng)的 sysfs 位置;(這里缺少 driver 符號鏈接說明這個設(shè)備當(dāng)前未使用內(nèi)核級的驅(qū)動程序)
resource0, resource0_wc, resource1, resource2 等是從"PCI 配置空間"解析出來的資源定義段落分別生成的,它們是 PCI 總線驅(qū)動在 PCI 設(shè)備初始化階段加上去的,都是二進制屬性,但沒有實現(xiàn)讀寫接口,只支持 mmap 內(nèi)存映射接口,嘗試進行讀寫會提示 IO 錯誤,其中 _wc 后綴表示 "合并式寫入(write combined)" ,它們用于作應(yīng)用程序的內(nèi)存映射,就可以訪問對應(yīng)的 PCI 設(shè)備上相應(yīng)的內(nèi)存資源段落;
有了 PCI 核心對 Linux sysfs 的完善支持,每個設(shè)備甚至不用單獨的驅(qū)動程序,如這里的 "0000:01:00.0" 不需要一個內(nèi)核級的驅(qū)動程序,有了 PCI 核心對該設(shè)備的配置空間發(fā)現(xiàn)機制,可以自動發(fā)現(xiàn)它的各個不同段落的資源屬性,在 Xorg 應(yīng)用程序中可以直接以 "/usr/lib/xorg/modules/drivers/sis_drv.so" 這個用戶空間的驅(qū)動程序?qū)ζ溥M行映射,就可以直接操作此視頻卡了;有了這一個 PCI 設(shè)備的示例可以知道,有了一個 PCI 設(shè)備的 /sys/devices/ 設(shè)備對象,去訪問它的各項屬性和設(shè)置屬性都非常簡單。以上介紹Linux sysfs桌面系統(tǒng)應(yīng)用。
【編輯推薦】