对U盘、SD卡、硬盘、操作的时候,需要对设备热拔插以及设备自动挂载自动卸载进行处理。有些时候我们需要对设备名进行固定,比如:SD卡卡槽1插入的设备固定它的设备名为sd_card1。 设备插入时将sd_card1的各个分区自动挂载固定的目录上去,设备拔出的时候又可自动的卸载之前的挂载信息。这些需求在linux2.6以后的系统都可以通过udev来处理。udev的详细介绍可以上维基百科查看:https://zh.wikipedia.org/wiki/Udev 下面介绍udev的具体使用
说明:以下内容根据我嵌入式设备实际测试得来,仅供参考。
(一)查看设备信息:
操作udev,可以使用udevadm命令,如果我们要查看/dev/sda 设备节点信息,我们可以使用下面命令:
命令:udevadm info -a --name=sda
信息结果:
~ # udevadm info -a --name=sda
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/platform/ahci.0/ata1/host0/target0:0:0/0:0:0:0/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
DRIVER==""
ATTR{ro}=="0"
ATTR{size}=="976773168"
ATTR{stat}==" 601 0 797 2680 0 0 0 0 0 560 2680"
ATTR{range}=="16"
ATTR{discard_alignment}=="0"
ATTR{events}==""
ATTR{ext_range}=="256"
ATTR{events_poll_msecs}=="-1"
ATTR{alignment_offset}=="0"
ATTR{inflight}==" 0 0"
ATTR{removable}=="0"
ATTR{capability}=="d0"
ATTR{events_async}==""
looking at parent device '/devices/platform/ahci.0/ata1/host0/target0:0:0/0:0:0:0':
KERNELS=="0:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{rev}=="MC10"
ATTRS{type}=="0"
ATTRS{scsi_level}=="6"
ATTRS{model}=="TOSHIBA MK5061GS"
ATTRS{state}=="running"
ATTRS{unload_heads}=="0"
ATTRS{queue_type}=="simple"
ATTRS{modalias}=="scsi:t-0x00"
ATTRS{iodone_cnt}=="0x281"
ATTRS{iorequest_cnt}=="0x281"
ATTRS{queue_ramp_up_period}=="120000"
ATTRS{timeout}=="30"
ATTRS{evt_media_change}=="0"
ATTRS{ioerr_cnt}=="0x0"
ATTRS{queue_depth}=="31"
ATTRS{vendor}=="ATA "
ATTRS{device_blocked}=="0"
ATTRS{iocounterbits}=="32"
looking at parent device '/devices/platform/ahci.0/ata1/host0/target0:0:0':
KERNELS=="target0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/platform/ahci.0/ata1/host0':
KERNELS=="host0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/platform/ahci.0/ata1':
KERNELS=="ata1"
SUBSYSTEMS==""
DRIVERS==""
looking at parent device '/devices/platform/ahci.0':
KERNELS=="ahci.0"
SUBSYSTEMS=="platform"
DRIVERS=="ahci"
ATTRS{modalias}=="platform:ahci"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
~ #
这里对上面的几个常用做说明
匹配键:"==","!="
赋值键:"=","+=",":=
KERNEL - 匹配设备的内核名字
SUBSYSTEM - 匹配设备的子系统
DRIVER - 匹配设备驱动名
NAME - 应当被采用为设备节点的名字
SYMLINK - 一系列被作为设备节点替补名字的符号链接
(二)固定设备节点名字
对于可热拔插的设备,比如说U盘,SD卡,最开始插入的设备设备节点名是sda,接着是sdb,也就是说只从dev下面的设备节点名是不能区分我们插入的是那个设备,这时我们可以通过udev 将设备节点与设备绑定,方法就是通过内核名字建立连接,连接到设备节点上。
目录结构如下:
/etc/udev # pwd
/etc/udev
/etc/udev # tree
.
├── rules.d
│ └── 99-mount.rules
│ └── 01-rename.rules
└── udev.conf
udev.conf
# udev.conf
# The initial syslog(3) priority: "err", "info", "debug" or its
# state can be changed with: "udevcontrol log_priority=<value>".
udev_root="/dev/"
udev_rules="/etc/udev/rules.d"
udev_log="err"
01-rename.rules
KERNEL=="*", OWNER="root" GROUP="root", MODE="0600"
#################################
#SD Card Device
#################################
KERNELS=="1-2.3",KERNEL=="sd*",SYMLINK+="usbsda%n",OPTIONS="ignore_remove"
KERNELS=="1-2.4",KERNEL=="sd*",SYMLINK+="usbsdb%n",OPTIONS="ignore_remove"
KERNELS=="1-2.2",KERNEL=="sd*",SYMLINK+="usbsdc%n",OPTIONS="ignore_remove"
################################
#USB Device
################################
KERNELS=="1-2.1",KERNEL=="sd*",SYMLINK+="usbmmc%n",OPTIONS="ignore_remove"
################################
#DISK Device
################################
KERNELS=="host0",KERNEL=="sd*",SYMLINK+="disksda%n",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="00",SYMLINK+="ttyCOM0",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="01",SYMLINK+="ttyCOM1",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="02",SYMLINK+="ttyCOM2",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="03",SYMLINK+="ttyCOM3",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="04",SYMLINK+="ttyCOM4",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="05",SYMLINK+="ttyCOM5",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="06",SYMLINK+="ttyCOM6",OPTIONS="ignore_remove"
KERNEL=="ttyUSB*",ATTRS{bInterfaceNumber}=="07",SYMLINK+="ttyCOM7",OPTIONS="ignore_remove"
插入SD卡,我们可以看到,设备节点被链接成固定的名字usbsda
查看设备节点:
brw------- 1 root root 8, 1 Jul 8 00:22 sda1
brw------- 1 root root 8, 2 Jul 8 00:22 sda2
brw------- 1 root root 8, 3 Jul 8 00:22 sda3
lrwxrwxrwx 1 root root 4 Jul 8 00:22 usbsda1 -> sda1
lrwxrwxrwx 1 root root 4 Jul 8 00:22 usbsda2 -> sda2
lrwxrwxrwx 1 root root 4 Jul 8 00:22 usbsda3 -> sda3
drwxr-xr-x 2 root root 60 Jul 8 00:22 bsg
brw------- 1 root root 8, 0 Jul 8 00:22 sda
crw------- 1 root root 21, 0 Jul 8 00:22 sg0
lrwxrwxrwx 1 root root 3 Jul 8 00:22 usbsda -> sda
(三)热拔插自动挂载,卸载
自动挂载和自动卸载在99-mount.rules脚本中设置,这里设置了2个硬盘和2个SD卡设备的自动挂载,设计每个设备最大有18个分区并且将所有的分区都挂载上去。
KERNEL=="*", OWNER="root" GROUP="root", MODE="0600"
##############################################
#Disk A device
##############################################
ACTION=="add",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_1",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mkdir /opt/disk_sda_1",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/disksda1 /opt/disk_sda_1",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/fuser -k /opt/disk_sda_1"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_1"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/rmdir /opt/disk_sda_1",OPTIONS="ignore_remove"
ACTION=="add",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_2",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mkdir /opt/disk_sda_2",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/disksda2 /opt/disk_sda_2",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/fuser -k /opt/disk_sda_2"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_2"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/rmdir /opt/disk_sda_2",OPTIONS="ignore_remove"
ACTION=="add",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_3",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mkdir /opt/disk_sda_3",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/disksda3 /opt/disk_sda_3",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/fuser -k /opt/disk_sda_3"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_3"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/rmdir /opt/disk_sda_3",OPTIONS="ignore_remove"
ACTION=="add",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_4",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mkdir /opt/disk_sda_4",
ACTION=="add",KERNELS=="1-1",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/disksda4 /opt/disk_sda_4",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/fuser -k /opt/disk_sda_4"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/umount -l /opt/disk_sda_4"
ACTION=="remove",KERNELS=="1-1",RUN+="/bin/rmdir /opt/disk_sda_4",OPTIONS="ignore_remove"
##############################################
#SD Card Device
##############################################
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_1",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mkdir /opt/usb_sd1_1",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/usbsda1 /opt/usb_sd1_1",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/fuser -k /opt/usb_sd1_1"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_1"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/rmdir /opt/usb_sd1_1",OPTIONS="ignore_remove"
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_2",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mkdir /opt/usb_sd1_2",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/usbsda2 /opt/usb_sd1_2",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/fuser -k /opt/usb_sd1_2"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_2"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/rmdir /opt/usb_sd1_2",OPTIONS="ignore_remove"
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_3",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mkdir /opt/usb_sd1_3",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/usbsda3 /opt/usb_sd1_3",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/fuser -k /opt/usb_sd1_3"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_3"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/rmdir /opt/usb_sd1_3",OPTIONS="ignore_remove"
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_4",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mkdir /opt/usb_sd1_4",
ACTION=="add",KERNELS=="1-2.3",RUN+="/bin/mount -t vfat -o rw,utf8=true,flush /dev/usbsda4 /opt/usb_sd1_4",OPTIONS="ignore_remove"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/fuser -k /opt/usb_sd1_4"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/umount -l /opt/usb_sd1_4"
ACTION=="remove",KERNELS=="1-2.3",RUN+="/bin/rmdir /opt/usb_sd1_4",OPTIONS="ignore_remove"
插入SD卡,可以看到自动挂载的挂载的设备:
/etc/udev/rules.d # df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 32768 20852 11916 64% /
tmpfs 61964 4 61960 0% /dev
/dev/mtdblock3 4096 768 3328 19% /hi3520
/dev/mtdblock4 4096 800 3296 20% /mnt
/dev/mtdblock6 8192 1156 7036 14% /data
tmpfs 61964 0 61964 0% /App
tmpfs 61964 0 61964 0% /opt
tmpfs 61964 4 61960 0% /var
tmpfs 61964 60 61904 0% /etc/ppp
/dev/usbsda1 1044468 1027966 16502 98% /opt/usb_sd1_1
/dev/usbsda2 33538032 33161232 376800 99% /opt/usb_sd1_2
/dev/usbsda3 27903304 27525128 378176 99% /opt/usb_sd1_3
/etc/udev/rules.d #