123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- -------------
- MDEV Primer
- -------------
- For those of us who know how to use mdev, a primer might seem lame. For
- everyone else, mdev is a weird black box that they hear is awesome, but can't
- seem to get their head around how it works. Thus, a primer.
- -----------
- Basic Use
- -----------
- Mdev has two primary uses: initial population and dynamic updates. Both
- require sysfs support in the kernel and have it mounted at /sys. For dynamic
- updates, you also need to have hotplugging enabled in your kernel.
- Here's a typical code snippet from the init script:
- [0] mount -t proc proc /proc
- [1] mount -t sysfs sysfs /sys
- [2] echo /sbin/mdev > /proc/sys/kernel/hotplug
- [3] mdev -s
- Alternatively, without procfs the above becomes:
- [1] mount -t sysfs sysfs /sys
- [2] sysctl -w kernel.hotplug=/sbin/mdev
- [3] mdev -s
- Of course, a more "full" setup would entail executing this before the previous
- code snippet:
- [4] mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev
- [5] mkdir /dev/pts
- [6] mount -t devpts devpts /dev/pts
- The simple explanation here is that [1] you need to have /sys mounted before
- executing mdev. Then you [2] instruct the kernel to execute /sbin/mdev whenever
- a device is added or removed so that the device node can be created or
- destroyed. Then you [3] seed /dev with all the device nodes that were created
- while the system was booting.
- For the "full" setup, you want to [4] make sure /dev is a tmpfs filesystem
- (assuming you're running out of flash). Then you want to [5] create the
- /dev/pts mount point and finally [6] mount the devpts filesystem on it.
- -------------
- MDEV Config (/etc/mdev.conf)
- -------------
- Mdev has an optional config file for controlling ownership/permissions of
- device nodes if your system needs something more than the default root/root
- 660 permissions.
- The file has the format:
- [-][envmatch]<device regex> <uid>:<gid> <permissions>
- or
- [envmatch]@<maj[,min1[-min2]]> <uid>:<gid> <permissions>
- or
- $envvar=<regex> <uid>:<gid> <permissions>
- For example:
- hd[a-z][0-9]* 0:3 660
- The config file parsing stops at the first matching line. If no line is
- matched, then the default of 0:0 660 is used. To set your own default, simply
- create your own total match like so:
- .* 1:1 777
- You can rename/move device nodes by using the next optional field.
- <device regex> <uid>:<gid> <permissions> [=path]
- So if you want to place the device node into a subdirectory, make sure the path
- has a trailing /. If you want to rename the device node, just place the name.
- hda 0:3 660 =drives/
- This will move "hda" into the drives/ subdirectory.
- hdb 0:3 660 =cdrom
- This will rename "hdb" to "cdrom".
- Similarly, ">path" renames/moves the device but it also creates
- a direct symlink /dev/DEVNAME to the renamed/moved device.
- You can also prevent creation of device nodes with the 4th field as "!":
- tty[a-z]. 0:0 660 !
- pty[a-z]. 0:0 660 !
- If you also enable support for executing your own commands, then the file has
- the format:
- <device regex> <uid>:<gid> <permissions> [=path] [@|$|*<command>]
- or
- <device regex> <uid>:<gid> <permissions> [>path] [@|$|*<command>]
- or
- <device regex> <uid>:<gid> <permissions> [!] [@|$|*<command>]
- For example:
- ---8<---
- # block devices
- ([hs]d[a-z]) root:disk 660 >disk/%1/0
- ([hs]d[a-z])([0-9]+) root:disk 660 >disk/%1/%2
- mmcblk([0-9]+) root:disk 660 >disk/mmc/%1/0
- mmcblk([0-9]+)p([0-9]+) root:disk 660 >disk/mmc/%1/%2
- # network devices
- (tun|tap) root:network 660 >net/%1
- ---8<---
- The special characters have the meaning:
- @ Run after creating the device.
- $ Run before removing the device.
- * Run both after creating and before removing the device.
- The command is executed via the system() function (which means you're giving a
- command to the shell), so make sure you have a shell installed at /bin/sh. You
- should also keep in mind that the kernel executes hotplug helpers with stdin,
- stdout, and stderr connected to /dev/null.
- For your convenience, the shell env var $MDEV is set to the device name. So if
- the device "hdc" was matched, MDEV would be set to "hdc".
- ----------
- FIRMWARE
- ----------
- Some kernel device drivers need to request firmware at runtime in order to
- properly initialize a device. Place all such firmware files into the
- /lib/firmware/ directory. At runtime, the kernel will invoke mdev with the
- filename of the firmware which mdev will load out of /lib/firmware/ and into
- the kernel via the sysfs interface. The exact filename is hardcoded in the
- kernel, so look there if you need to know how to name the file in userspace.
- ------------
- SEQUENCING
- ------------
- Kernel does not serialize hotplug events. It increments SEQNUM environmental
- variable for each successive hotplug invocation. Normally, mdev doesn't care.
- This may reorder hotplug and hot-unplug events, with typical symptoms of
- device nodes sometimes not created as expected.
- However, if /dev/mdev.seq file is found, mdev will compare its
- contents with SEQNUM. It will retry up to two seconds, waiting for them
- to match. If they match exactly (not even trailing '\n' is allowed),
- or if two seconds pass, mdev runs as usual, then it rewrites /dev/mdev.seq
- with SEQNUM+1.
- IOW: this will serialize concurrent mdev invocations.
- If you want to activate this feature, execute "echo >/dev/mdev.seq" prior to
- setting mdev to be the hotplug handler. This writes single '\n' to the file.
- NB: mdev recognizes /dev/mdev.seq consisting of single '\n' character
- as a special case. IOW: this will not make your first hotplug event
- to stall for two seconds.
|