Linux

Saturday, July 16, 2005

Udev rules

A bit of history:

In linux the devices are represented as a file in the device directory /dev that is used by other user space programs to access the device.A typical example is /dev/ttyS0 that represents the first serial port in the machine. Each and every device has a unique major and minor number. But the /dev directory is too big. I found some 10000+ entries in a Linux distro in the /dev directory which makes it almost impossible to keep track of the associations between the device file and the device. For this the devfs concept evolved (thank god I haven’t worked much on the devfs now it has been removed from the kernel), which helps in creating the device nodes as and when the device is connected.

Udev:

udev run’s in user space and it is userspace device file system and it helps to create a dynamic /dev .It makes use of the hotplug events to accomplish its goals.To work with udev we need to create udev rules. Udev’s rules are in /etc/udev/rules.d directory.More info on udev can be found from [4].Udev makes use of the sysfs file system in the 2.6 kernels.To make use of udev we need to create udev rules.

A udev rule defines the mapping between a device's attributes and the desired device filename. Default udev rules can be found in the /etc/udev/rules.d/50-udev.rules file. Files in the rules.d directory are parsed in the lexical order. When the udev finds a matching rule it stops parsing and the rule is applied.we can create our own rules the rule filename should have the .rules suffix.I prefer to create my own rules file .

Details on writing udev rules can be found from [2] or [4].

Here is an example:

BUS="usb", SYSFS{idVendor}="04e6", SYSFS{idProduct}="e001", NAME="usb/mydev%n"

This rule specifies to create the node mydev%n in the usb directory of /dev.When the device is plugged in after the drivers are loaded the sysfs nodes are created.When the vendor and product ids specified in the rule matches the one in sysfs the device node is created which is purely dynamic.when the device is unplugged the device node is removed.

udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group), which is configured by the default_mode setting inside /etc/udev/udev.conf. There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the MODE assignment key,as in MODE="0666"

Related Links:

[1] http://www.lanana.org/

[2] http://www.linuxjournal.com/article/7316

[3] http://www.linuxjournal.com/article/7496

[4] http://www.reactivated.net/writing_udev_rules.html

[5] http://kernel.org/pub/linux/utils/kernel/hotplug/udev_vs_devfs

[6] http://kerneltrap.org/node/5340

Friday, July 15, 2005

Version dependency

Kernel interfaces change from kernel to kernel in that case modules need to be compatible with both versions of kernel.
The need for this occasionally arise.The header file < linux/version.h > contains the related macros.This header is automatically included by module.h.

LINUX_VERSION_CODE macro expands to the kernel version release number.E.g:the 2.6.10 kernel is represented as 132618(0x02060a).

KERNEL_VERSION(x,y,z) macro builds the integer corresponding to the given kernel version.
E.g:KERNEL_VERSION(2,6,10) will expand to 132618 that can be used to compare the kernel version.

This can be used with #ifdef to workaround the kernel related interface changes.

An example:

The usb_unlink_urb has been changed to usb_kill_urb with 2.6.10 kernel.(http://kerneltrap.org/files/ChangeLog-2.6.10 )

To handle this verson related change the above discussed macros can be used as in this code snippet:

#include < linux/version.h >

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
usb_unlink_urb(bulk_out_urb);
#else
usb_kill_urb(bulk_out_urb);
#endif