Linux下针对特定硬件外设锁定路径的方法

在Linux系统编程及嵌入式编程中,输入输出的基本方法就是读写访问/dev目录下的对应设备文件。例如,最常见的/dev/ttyUSBx设备对应于插入的USB-UART转接器;/dev/videox设备对应于摄像头设备。其中,设备名称结尾的x代指Linux内核为多个同种设备的编号id。实际工作中发现,Linux内核仅仅是按照发现设备的顺序从0开始依次编号,并不对设备号的顺序做出任何保证,并且在设备移除后,id保留一段时间后被新插入的设备复用。由于以上原因,即便是多次启动也可能带来对同一硬件设备的不同编号,故默认设备名不能固定,必须通过人为判断输入,给用户带来了麻烦。
其实,Linux系统已经内置针对这一问题的解决办法。


在目录/etc/udev/rules.d内,可以建立.rules文件,比如
/etc/udev/rules.d/50-udev.rules

加入语句

KERNEL=="hdb", NAME="my_disk"

匹配被内核命名为”hdb”的设备,重命名为 /dev/my_disk

KERNEL=="hdb", DRIVER=="ide-disk", SYMLINK+="sparedisk"

匹配被内核命名为”hdb”且驱动程序哦为”ide-disk”的设备,以默认名称命名,并创建一个符号链接/dev/sparedisk指向该设备

在规则中可以使用预设变量和通配符。比如:

  • 用%k表示设备名
KERNEL=="mice", NAME="input/%k"

会将/dev/mice设备转移到/dev/input/mice出现

  • 用%n表示设备编号
KERNEL=="loop0", NAME="loop/%n", SYMLINK+="%k"

会将/dev/loop设备转移到/dev/loop/0,并在/dev/loop0创建一个符号链接

  • 常用通配符 * ? []
KERNEL=="fd[0-9]*", NAME="floppy/%n", SYMLINK+="%k"

匹配所有软盘设备,并转移到/dev/floppy文件夹下,以对应设备号命名,并在原位置创建符号链接

KERNEL=="hiddev*", NAME="usb/%k"

将所有以hiddev开头的设备移动到/dev/usb/文件夹内


理论上,这样能够解决相当一部分设备的重命名问题。但是,若计算机插入了多个同类设备,则这一方法无力区分。解决办法是利用SUBSYSTEM和ATTRS关键字,沿设备树向上搜索,找到每个设备独有的特征标识,并将其写到规则文件里。为了查看设备的特征标识,可以选用以下几个命令:

find /sys -name dev

在sys文件树中寻找dev设备节点路径

udevadm info  --name=/dev/ttyUSB1 --attribute-walk

udevinfo -a -p /sys/block/sda

搜索驱动树


几个例子

  • 打印机原名为 /dev/lp0
# udevinfo -a -p $(udevinfo -q path -n /dev/lp0)
  looking at device '/class/usb/lp0':
    KERNEL=="lp0"
    SUBSYSTEM=="usb"
    DRIVER==""
    ATTR{dev}=="180:0"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb1/1-1':
    SUBSYSTEMS=="usb"
    ATTRS{manufacturer}=="EPSON"
    ATTRS{product}=="USB Printer"
    ATTRS{serial}=="L72010011070626380"

其中有特征标识serial=”L72010011070626380”,故写

SUBSYSTEM=="usb", ATTRS{serial}=="L72010011070626380", SYMLINK+="epson_680"

  • USB Palm Pilot
    原名为/dev/ttyUSB1,规则写为
SUBSYSTEMS=="usb", ATTRS{product}=="Palm Handheld", KERNEL=="ttyUSB*", SYMLINK+="pilot"

依次匹配usb设备,生产商Palm Handheld,设备类型ttyUSB


  • USB摄像头
    摄像头有时会被辨认为单个分区的磁盘设备,比如/dev/sdb /dev/sdb1
#udevinfo -a -p $(udevinfo -q path -n /dev/sdb1)
  looking at device '/block/sdb/sdb1':
    KERNEL=="sdb1"
    SUBSYSTEM=="block"

  looking at parent device '/devices/pci0000:00/0000:00:02.1/usb1/1-1/1-1:1.0/host6/target6:0:0/6:0:0:0':
    KERNELS=="6:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{rev}=="1.00"
    ATTRS{model}=="X250,D560Z,C350Z"
    ATTRS{vendor}=="OLYMPUS "
    ATTRS{scsi_level}=="3"
    ATTRS{type}=="0"

我们只需要用/dev/sdb1,但是由于驱动树的关系,所有匹配sdb1的特征也会匹配sdb。为了区分,还需要对应设备名进行匹配:

KERNEL=="sd?1", SUBSYSTEMS=="scsi", ATTRS{model}=="X250,D560Z,C350Z", SYMLINK+="camera"

  • USB硬盘
KERNEL=="sd*", SUBSYSTEMS=="scsi", ATTRS{model}=="USB 2.0 Storage Device", SYMLINK+="usbhd%n"

这个规则不会改变原设备名,而会创建以下符号链接
/dev/usbhd - 可用fdisk分区的节点
/dev/usbhd1 - 第一分区
/dev/usbhd2 - 第二分区

参考原文:
http://www.reactivated.net/writing_udev_rules.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值