How to set up mdev rules for Busybox

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.

#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.

# /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:

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.

#!/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.

Geschrieben in Linux,Sysadmin | 2 Kommentare

2 Kommentare bisher

RSS Feed abonnieren

  1. 8. März 2010 um 11:25 Uhr

    ossy sagt,

    Thanks for a helpful howto! My setup works mostly but there is a one problem.

    I have tried hotplugging regular pl2303 serial converter on a at91rm9200-ek board. Problem is script spesified in a mdev.conf file does not execute when hotplugging. Owners and permissions sets but script does not execute. With coldplug ( == mdev -s ) also script executes. What is different when hotplugging?

    My mdev.conf:

    # cat /etc/mdev.conf
    ttyUSB[0-9]* 1:1 660 */root/hello.sh

    I have required drivers in a kernel (v. 2.6.27) and everything works fine. Device node is created when converter attached and destroyed when unattached. Created node works fine. As I said script executes when coldplugging but only perms and owners sets when hotplugging.

    Snip from docs/mdev.txt: „You should also keep in mind that the kernel executes hotplug helpers with stdin,
    stdout, and stderr connected to /dev/null.“

    Is this thing different between hotplugging and coldplugging?

    I made this kind of nodes:

    # ls -l /dev/std*
    lrwxrwxrwx 1 0 0 4 Mar 8 08:32 /dev/stderr -> fd/2
    lrwxrwxrwx 1 0 0 4 Mar 8 08:32 /dev/stdin -> fd/0
    lrwxrwxrwx 1 0 0 4 Mar 8 08:32 /dev/stdout -> fd/1

    But mentioned script still not execute!

  2. 8. März 2010 um 12:11 Uhr

    ossy sagt,

    Thanks for a helpful howto!

    My setup works fine but I have one problem.

    Script called in a mdev.conf file does not execute when hotplugging. When coldplugging both owners & perms sets and given script executes but when hotplugging only owners & perms sets.

    My mdev.conf:

    # cat /etc/mdev.conf
    ttyUSB[0-9]* 1:1 660 */root/hello.sh

    As I said everything else works fine (device node is created and destroyed, device node works when it exists and so on) but execution of a given script does not success.

    Any advices to solve this kind of problem?

Kommentare sind deaktiviert.