I struggled while setting up mdev rules to gain control about how device file nodes ( /dev/ttyUSB3) are created. This short HOWTO should help, to set up mdev within BusyBox Linux.
What’s mdev for: Mdev is a minimal clone of udev. Imagine an embedded device uses an USB-RS232 converter at /dev/ttyUSB0: Now you would like to use an USB wireless modem which normally gets attached at the device nodes at /dev/ttyUSB0 to /dev/ttyUSB6. It’s not predictable on which /dev nodes these two devices (the converter and the usb modem) get attached. Sometimes the converter gets USB0, somtimes the modems uses the USB[0-5]. That’s the moment mdev jumps on the stage. It allows you, to intercept the hotplug messages from the kernel and do some actions (execute scripts, create symlinks) in the user space.
How to set-up up mdev: MDEV has to be selected when compiling BusyBox. After Busybox is compiled and installed with mdev support, just follow the instruction in docs/mdev.txt http://svn.dd-wrt.com:8000/dd-wrt/browser/src/router/busybox/docs/mdev.txt?rev=9719 to get mdev working.
Pitfall during installation: To boot Linux and to execute a start-up script the two device nodes /dev/null and /dev/console should exist. These two devices have to exist BEFORE mdev creates them. It’s possible to statically create these two nodes in the /dev directory. Later, during the boot process, the /dev directory gets replaced by the ramdisk /dev created by mdev.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#create a temporary mount point
mkdir
tmpMount
mount
--bind / tmpMount
cd
tmpMount
/dev
ls
#create the necessary device nodes
mknod
-m 660 console c 5 1
mknod
-m 660 null c 1 3
/dev
#don't forget to delete the temporary mount point
cd
../..
umount
tmpMount
rmdir
tmpMount
|
And now write the mdev rules: Your mdev installation works, thus mdev creates a complete /dev directory containing all present hardware nodes. Now it’s time to gain control about the hardware plugged in. The config file /etc/mdev.conf defines what happens, when a device gets plugged in or out.
1
2
3
4
5
|
# /etc/mdev.conf
# Fire the setupUSBdev script if a device named ttyUSB* gets plugged:
ttyUSB[0-9]* 0:0 660 @
/usr/bin/ladybug/setupUSBdev
# let mdev create a symbolic link to modem for any ACM device:
ttyACM[0-9]* ->modem
|
The first line in this code snippet defines that, if a serial USB device (formerly known as ttyUSB*) gets plugged in, the script setupUSBdev will be executed. All necessary information to identify the device and to decide where to create the node file are provided in environmental variables. The following listening shows what the script knows about the new device:
1
2
3
4
5
6
7
8
9
10
11
|
ACTION=add
SEQNUM=1018
MAJOR=188
MDEV=ttyUSB6
DEVPATH=/class/tty/ttyUSB6
SUBSYSTEM=tty
MINOR=6
PHYSDEVPATH=/devices/pci0000:00/0000:00:0b.0/usb2/2-1/2-1.3/2-1.3:1.6/ttyUSB6
PHYSDEVDRIVER=sierra
PHYSDEVBUS=usb-serial
PWD=/dev
|
Your free to gain more information from the PHYSDEVPATH in /sys/. But for simply identify the device, the environmental variables provide enough information. By the way: This document from Rob Landley (author of mdev) explains more about obtaining information from hot-plugged devices.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/bin/sh
# Create device files for sierra wirless modems
# Device Types
WIRELESS=
"sierra"
logger
"Mdev $ACTION event for $PHYSDEVDRIVER @ $MDEV"
#check if PHYSDEVDRIVER is set
if
[
"$PHYSDEVDRIVER"
=
""
];
then
# No idea why we receive two events for each new device....
exit
fi
# catch device driver
if
[
"$PHYSDEVDRIVER"
=
"$WIRELESS"
];
then
logger -t $0
"Wireless Modem ($MDEV) detected"
# get highest node file
HIGHEST=`
ls
/dev/sierrattyUSB
* |
tail
-1 |
tr
-
cd
'[[:digit:]]'
`
logger -t $0
"Actual highest dev File = $HIGHEST"
if
[
"$HIGHEST"
=
""
];
then
Logger -t $0
"$MDEV is the first node. It get's /dev/sierrattyUSB0"
ln
-sf
/dev/
${MDEV}
/dev/sierrattyUSB0
else
NEXT=$(($HIGHEST + 1))
Logger -t $0
"Next DevFile ist # $NEXT"
ln
-sf
/dev/
${MDEV}
/dev/sierrattyUSB
${NEXT}
fi
fi
|
This silly script checks if there are allready any /dev/sierrattyUSB* devices. It creates well defined simlinks to the original /dev/files. No matter if the six device nodes (a Sierra USB modem provides six serial ports) start at 0, 1 or any other position. The first node of the modem will allways be available at /dev/sierrattyUSB0.
Next step would be a script which handles the removal of the device…
Mdev allows to react on hot plugged hardware. It gets possible to let the application react on hardware events: “You plugged in XY. would you like to…”. My aim in using mdev, was to be sure where new plugged in devices get attached in /dev. It works.
每个hotplug事件导出到user空间的变量不一样的,想知道有哪些变量可用,可以写一个脚本:
mmcblk[0-9]p[0-9] root:root 660 */etc/udev/rules.d/fuck.sh
fuck.sh内容 :
env > /tmp/env
插上SD卡后,/tmp/env内容:
DEVNAME=mmcblk0p1
ACTION=add
SHLVL=2
HOME=/
SEQNUM=713
MAJOR=179
MDEV=mmcblk0p1
DEVPATH=/devices/platform/omap/omap_hsmmc.0/mmc_host/mmc0/mmc0:1234/block/mmcblk0/mmcblk0p1
SUBSYSTEM=block
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MINOR=1
PWD=/dev
DEVTYPE=partition
再修改fuck.sh脚本,让SD卡插入和移除时自动挂载和从文件系统移除:
if [ "${ACTION}" == "add" ]
then
mount ${PWD}/${DEVNAME} /mnt
elif [ "${ACTION}" == "remove" ]
then
umount /mnt
fi