3. sysfs与设备模型
在Linux用户空间设备管理中,sysfs是内核设备模型向用户空间暴露的“结构化视图”。它通常挂载在/sys,以目录和文件的形式呈现设备、驱动、总线及其相互关系。与/dev下的设备节点不同,/sys不用于读写数据流,而是用于观察拓扑、查询属性、触发匹配、调试绑定。理解sysfs,核心是理解内核设备模型中的几个基本对象:kobject、kset、device、driver、bus,以及它们如何被组织成可遍历的树。
一、核心原理:从kobject到设备模型
内核设备模型的最小基石是kobject。它本身不直接面向用户空间,而是提供引用计数、父子层级、sysfs目录项等基础能力。多个kobject可以组成kset,kset是一种容器,用于把同类kobject聚合在一起,并形成层级。用户空间看到的每一个/sys目录,通常对应一个kobject;目录中的属性文件,则对应kobject的attribute。
在此之上,内核抽象出三类关键对象:
- bus:总线类型,如
pci、usb、platform,负责设备与驱动的匹配规则。 - device:具体设备实例,描述“有什么硬件”。
- driver:设备驱动,描述“如何操作硬件”。
bus、device、driver三者通过sysfs中的符号链接和目录形成关系网。设备注册到总线后,总线负责寻找匹配驱动;驱动注册到总线后,总线负责寻找匹配设备。匹配成功后,双方在sysfs中建立绑定链接。因此,/sys不仅是信息展示,更是设备-驱动匹配状态的实时映射。
二、/sys目录结构与遍历方法
/sys下最常用的顶层目录包括:
| 目录 | 含义 | 典型用途 |
|---|---|---|
/sys/bus/ |
按总线类型组织 | 查看某总线下所有设备和驱动 |
/sys/devices/ |
全局设备树 | 按物理拓扑遍历设备层级 |
/sys/class/ |
按功能分类 | 快速定位网卡、块设备、tty等 |
/sys/block/ |
块设备视图 | 查看磁盘及分区 |
/sys/module/ |
内核模块信息 | 查看模块参数与引用计数 |
遍历sysfs时,最有效的方式是从bus出发,沿devices和drivers两个方向展开。例如查看PCI总线上的设备与驱动绑定情况:
# 列出PCI总线下的所有设备
ls /sys/bus/pci/devices/
# 列出PCI总线下的所有驱动
ls /sys/bus/pci/drivers/
# 查看某设备绑定的驱动(符号链接)
ls -l /sys/bus/pci/devices/0000:00:1f.2/driver
# 查看某驱动绑定的所有设备
ls /sys/bus/pci/drivers/ahci/
另一个重要入口是/sys/devices,它反映的是设备的物理拓扑。例如从PCI根桥逐级向下,可以看到桥、控制器、终端设备。使用find或ls -R可以递归遍历,但更推荐结合readlink查看符号链接,理解设备与驱动、设备与类之间的多对多关系。
三、案例:定位一块网卡的完整信息链
假设需要排查eth0对应的硬件、驱动和总线信息,可以按以下路径遍历:
# 1. 从class找到设备
ls -l /sys/class/net/eth0
# 输出类似:eth0 -> ../../devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0
# 2. 进入设备目录查看属性
cd /sys/class/net/eth0
cat address # MAC地址
cat speed # 链路速率
cat operstate # 运行状态
# 3. 查看绑定的驱动
ls -l /sys/class/net/eth0/device/driver
# 输出类似:driver -> ../../../../bus/pci/drivers/e1000e
# 4. 查看所属总线
ls /sys/class/net/eth0/device/subsystem
# 输出类似:subsystem -> ../../../../bus/pci
这条链路清晰展示了:class入口 → device实例 → driver绑定 → bus归属。在udev规则编写中,这种遍历能力非常关键,因为udev规则常需要根据SUBSYSTEM、DRIVER、ATTR{}等条件匹配设备。
四、误区与复盘
常见误区一:把/sys当作/dev使用。 /sys中的属性文件通常用于查询和配置,不是数据读写通道。例如/sys/class/net/eth0/address只读,不能用来发送网络数据。
常见误区二:忽略符号链接。 sysfs中大量关系通过符号链接表达,如driver、subsystem、device。直接ls看不到真实路径,应使用ls -l或readlink -f。
常见误区三:认为目录层级等于物理层级。 /sys/class是按功能分类的视图,/sys/devices才是物理拓扑。两者通过符号链接关联,不能混为一谈。
遍历建议:排查设备问题时,优先使用/sys/bus/<bus>/devices/和/sys/bus/<bus>/drivers/交叉比对;编写udev规则时,优先使用udevadm info -a -p /sys/class/...自动提取属性链,避免手工拼路径。
掌握sysfs的设备模型,本质上是掌握一种“内核视角的设备关系语言”。kobject和kset提供底层骨架,bus、device、driver构成匹配与绑定的三角关系,而/sys则是这套关系在用户空间的可读投影。能够熟练遍历/sys,就能在设备管理、驱动调试和udev规则编写中快速定位问题根因。