分类: LINUX
2015-03-29 00:59:29
原文地址:Linux 内核/sys 文件系统之uevent 作者:cdxffaaaa
这些 uevent 属性文件一般都是可写的,其中 /sys/devices/ 树下的很多 uevent 属性在较新内核下还支持可读:
# find /sys/ -type f -name uevent -ls 11 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/uevent 1471 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/pcspkr/uevent 3075 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/vesafb.0/uevent 3915 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/serial8250/uevent 3941 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/serial8250/tty/ttyS2/uevent 3950 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/serial8250/tty/ttyS3/uevent 5204 0 -rw-r--r-- 1 root root 4096 12月 12 21:10 /sys/devices/platform/i8042/uevent [...] 912 0 -rw-r--r-- 1 root root 4096 12月 12 21:17 /sys/devices/pci0000:00/0000:00:02.5/uevent [...] |
上面截取的最后一个是 SCSI 硬盘控制器设备的 uevent 属性文件,这些 /devices/ 属性文件都支持写入,当前支持写入的参数有 "add","remove","change","move","online","offline"。如,写入 "add",这样可以向 udevd 发送一条 netlink 消息,让它再重新一遍相关的 udev 规则文件;这个功能对开发人员调试 udev 规则文件很有用。
# echo add > /sys/devices/pci0000:00/0000:00:02.5/uevent |
使用驱动(PCI)的 sysfs 属性文件, bind, unbind 和 new_id
在设备驱动 /sys/bus/*/driver/... 下可以看到很多驱动都有 bind, unbind, new_id 这三个属性,
# find /sys/bus/*/drivers/ -name bind -ls
... |
每一个设备驱动程序在程序内以某种方式注明了可用于哪些硬件,如所有的 PCI 驱动都使用 MODULE_DEVICE_TABLE 声明了所能驱动的 PCI 硬件的 PCI 设备号。但驱动程序不能预知未来,未来生产的新的硬件有可能兼容现有硬件的工作方式,就还可以使用现有硬件驱动程序来工作。在 bind 和 unbind 发明以前,这种情况除了修改 PCI 设备驱动程序的 DEVICE_TABLE 段落,重新编译驱动程序,以外别无他法,在 2.6 内核上添加了 bind 和 unbind 之后可以在不重新编译的情况下对设备和驱动之间进行手工方式地绑定。
而且对于有些硬件设备可以有多份驱动可用,但任何具体时刻只能有一个驱动程序来驱动这个硬件,这时可以使用 bind/unbind 来强制使用和不使用哪一个驱动程序;(注意关于多种驱动程序的选择,更好的管理方法是使用 modprobe.conf 文件,需要重启才生效,而 bind/unbind 提供的是一种临时的无需重启立即生效的途径;)
使用它们可以强制绑定某个设备使用或强制不使用某个驱动程序,操作方法就是通过 bind 和 unbind 接口。
#find /sys/-type f ( -name bind -or -name unbind -or -name new_id ) |
这个结果中特别提到了 8139too 这份驱动程序的这三个属性文件,
# find /sys/bus/pci/drivers/8139too/ -ls 6435 0 drwxr-xr-x 2 root root 0 12月 12 22:08 /sys/bus/pci/drivers/8139too/ 6436 0 lrwxrwxrwx 1 root root 0 12月 12 22:08 /sys/bus/pci/drivers/8139too/0000:00:0e.0 -> |
这一段操作过程演示了如何对 PCI 设备 "0000:00:0e.0" 强制取消绑定 "8139too" 驱动和强制绑定 "8139too" 驱动:
对 unbind 属性写入总线号码(bus_id)即是强制取消绑定;
对 bind 属性写入总线号码(bus_id)即是强制绑定;
注意,它要求的写入的是总线号码,对应于PCI设备的总线号码是按照 "domain(4位):bus(2位):slot(2位):function号(不限)" 的方式组织,是可以从其设备 kobject 节点上找到,而其它类型的总线有各自不同的规则;
请特别注意: 在这一个例子中, "echo 0000:00:0e.0 > /sys/bus/pci/drivers/8139too/unbind" 这第一个写入命令以 "No such device" 为错误退出,而后续的 "echo -n" 命令则可以成功。这是因为内核在对总线号码进行匹配时过于严格了,通常的 "echo" 命令写入一个字符串会以一个换行符结束输出,内核所接收到的是带有这个换行符的 bus_id 字符串,将它与内核数据结构中的真正的 bus_id 字符串相比较,当然不能找到;所幸的是,这个问题在最新的 2.6.28 开发中的内核上已已经解决,它将这个比较函数改为一个特殊实现的字符串比较,自动忽略结尾处的换行符,在 2.6.28-rc6 内核上测试,不带"-n"参数的 echo 命令已经可以写入成功。
而 new_id 属性文件也可以以另一种途径解决新的设备号问题:它是一个只写的驱动属性,可用于向其中写新的设备号。它支持写入 2至7个十六进制整形参数,分别代表 vendor, device, subvendor, subdevice, class, class_mask, driver_data 最少为 2个是因为一个 PCI设备主要以厂商号(vendor)和设备号(device)所唯一标定,其它 5个参数如果不输入则缺省值为 PCI_ANY_ID(0xffff)。
5441 0 --w------- 1 root root 4096 12月 14 18:15 /sys/bus/pci/drivers/8139too/new_id |
从 8139too 驱动上可以看到它当前所静态支持的设备号码列表,其中包括当前系统中的设备 10ec:8139, 假设未来有一款 8140 设备也满足 8139 设备的硬件通讯协议,于是可以使用 8139too 驱动程序来驱动它,操作如下
# echo '10ec 8140' > /sys/bus/pci/drivers/8139too/new_id |
这在不更新驱动程序的情况下调试设备很有用处。