Links

McCoyFam Webmail (powered by Google Apps)

The Family

Mark McCoy - Me
Helen McCoy - My Mom
Nick McCoy - My Son

Linux Udev Presentation

This is the full text of a presentation prepared for the August meeting of the San Antonio Linux Users Group. For more information about satlug go to www.satlug.org.

Please feel free to download the actual openoffice presentation here.

Note: I still need to upload the last section of this page, sorry it has taken so long. :)

History of devices in Unix and Linux

The basic design of the Unix system is that everything should look like a file. Any program that needs to send or receive information to a device can open it, read from it (or write to it), and close it using the simple programming interfaces available for all files.

Traditionally, almost all devices attached to a Unix-type system are available under the /dev directory.

But, how do they get there?

Device nodes

The traditional Unix way of creating device nodes in /dev is through major and minor numbers. Major and minor numbers are part of the kernel API for devices. A major number refers to a device class, and a minor number refers to a specific device of that category. For example, look at the major/minor numbers for hard drives (columns 5 and 6 in an ls -l listing):

[neptune ~]$ ls -l /dev/hd*
brw-rw----  1 root disk 3, 0 2005-07-14 13:58 /dev/hda
brw-rw----  1 root disk 3, 1 2005-07-14 13:58 /dev/hda1
brw-rw----  1 root disk 3, 2 2005-07-14 13:58 /dev/hda2
brw-rw----  1 root disk 3, 3 2005-07-14 13:58 /dev/hda3
brw-rw----  1 root disk 3, 5 2005-07-14 13:58 /dev/hda5
brw-rw----  1 root disk 3, 6 2005-07-14 13:58 /dev/hda6
brw-rw----  1 root disk     3, 64 2005-07-14 17:02 /dev/hdb
brw-rw----  1 root disk     3, 65 2005-07-14 17:02 /dev/hdb1
brw-rw----  1 root optical 22,  0 2005-07-14 17:02 /dev/hdc

Creating device nodes

Tradtionally, the way to create a device node in /dev was to use the program mknod (1).

[neptune ~]$ mknod --help
Usage: mknod [OPTION]... NAME TYPE [MAJOR MINOR]

Of course, you had to know what type of device you had (block, character, special, FIFO) and the major and minor numbers for the device.

You also had to set up the permissions for the device node after creating it.

Problems with the tried and true

The old way was not very flexible, from a user's standpoint. It was designed to be set up once and then never changed. Typically, all device nodes possible were set up in /dev by the OS vendor, leading to a very large number of devices in /dev. The /dev directory contained many hundreds or thousands of entries for devices that weren't even attached to the system.

Devices could not be created “on-the fly” when new hardware was attached to the system. Plug and play devices like USB devices weren't handled well, if at all.

Running out of subdevices, terminal lines for example, was a problem. If you had only allocated a certain number of terminal entries in /dev, and you attached more terminals, you could not use them until you created more device nodes.

Kernel-space device management: devfs

The first device manager for linux was devfs. Devfs is a file system (like ext3 or reiserfs) that could create and manage device nodes. It had to be mounted at /dev for standard device usage, but it could also be mounted in other places in the file tree.

Devfs allowed for automatic loading of kernel modules whenever a device node was accessed.

Devfs seemed to be a good answer to the problems, but it wasn't quite as flexible as the users wanted it to be.

Some problems with devfs

Some of the problems of the non-managed /dev directory still existed, like the problem of having a huge /dev directory.

The feature of devfs to autoload a module when the device node was accessed turned out to cause problems with some modules when a device node was accessed without having a device attached to it.

The most important problem was that since devfs was part of the kernel, adding new device information was only possible by the kernel maintainers. The only way for users to get new devices added to their devfs system was by upgrading their kernel!

User-Space Device Manager: udev

And now, udev to the rescue!

udev is a user-mode daemon that has special permission by the kernel to work in the /dev directory. It is started at boot time and it is responsible for adding/removing device nodes, setting up permissions, symlinks, etc. Udev works with the hotplug system to manage devices on the fly as kernel modules get loaded or unloaded.

Since udev is only resonsible for maintenance of the /dev tree, another system was created to manage module loading and unloading on the fly. The hotplug system works with udev to recreate the functionality of devfs without the problems that devfs had.

Since udev is maintained outside of the kernel tree, updates to udev can be made rapidly, allowing new devices to be recognized much sooner than by waiting to upgrade the kernel.

The Benefits of Using udev

  • The combination of udev, hotplug, and sysfs allows for a much more flexible base to build a system on.
  • Devices can be given special names or permissions without modifying the kernel source.
  • Several devices can be bound together to create one device node (more on that later!!!)
  • Hotplugging devices works automagically, finally!!
  • Smaller /dev to work with (uses less memory than devfs)
  • Devfs support is officially deprecated by the kernel team, and will be removed from the 2.6 kernel in the future.

Migrating from a devfs to a udev System

Prerequisites

Using udev requires that your kernel and your distribution support udev, hotplug, and the /sys file system. Check with your distribution's support for more information about installing udev and hotplug support. Your distribution's initscript package should also support udev, since it must be able to load /sbin/udevd at boot time.

Building a udev-enabled kernel is quite simple. The only kernel option that you must enable is CONFIG_HOTPLUG. Once you are sure that udev is working properly, you can disable devfs support in your kernel permanently.

If devfs is compiled into your kernel, devfs will be used unless you pass a boot-time kernel parameter to disable devfs.

Booting a udev Kernel

Check to make sure that your kernel supports hotplug

[neptune ~]$ cat /proc/config.gz | gunzip | grep -i "CONFIG_HOTPLUG"
CONFIG_HOTPLUG=y
CONFIG_HOTPLUG_PCI_PCIE=m
# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI_FAKE=m
CONFIG_HOTPLUG_PCI_COMPAQ=m
# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
CONFIG_HOTPLUG_PCI_IBM=m
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_HOTPLUG_PCI_ACPI_IBM=m
CONFIG_HOTPLUG_PCI_CPCI=y
CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m
CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m
CONFIG_HOTPLUG_PCI_SHPC=m
# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set

Check to make sure you mount ''/sys'' as a sysfs filesystem

NOTE: Some distributions mount /sys automatically during their initscripts if the sysfs option is enabled in the kernel, others add an entry in fstab.

[neptune ~]$  mount | grep /sys
none on /sys type sysfs (rw)

If you do not have /sys loaded, make sure that sysfs support is enabled in your kernel. Use grep to look for “SYSFS” in /proc/config.gz or for “sysfs” in /proc/filesystems.

If your distribution doesn't automatically mount /sys in the initscripts, add an entry to /etc/fstab like this:

sysfs  /sys  sysfs  defaults 0 0

Check to make sure hotplug is installed

[neptune ~]$ ls /sbin/hotplug /sbin/udevd
/sbin/hotplug

If hotplug and udev are not installed, you can probably use your package management tools to install them (yum on Fedora, apt-get on debian, emerge on gentoo, pacman on arch, etc…). If not, you can download hotplug and udev at http://www.us.kernel.org/pub/linux/utils/kernel/hotplug/ and install them using the standard ”make ; make install” duo. The README files in these tarballs have a lot of good information about using hotplug and udev.

Check to make sure that your fstab file is good

One of the changes using devfs was that the way the disk drives were labelled changed. The old naming scheme was the familiar /dev/hda1, which changed to /dev/discs/disc0/part1. This scheme worked fine, unless you had mixed IDE and SCSI devices on your system and added or removed drives.

Udev reverts to the original naming scheme (thankfully), but a lot of distributions have configured udev to allow allow both devfs and udev names. If you try to boot using udev and you cannot mount your partitions properly, or if you want to use a udev-only system, you will need to modify your /etc/fstab to use the udev naming scheme for your hard drives.

# devfs naming scheme
/dev/discs/disc0/part1 /boot ext3     sync,noatime     0 0
/dev/discs/disc0/part2 swap  swap     defaults,noatime 0 0
/dev/discs/disc0/part5 /     reiserfs defaults,noatime 0 0
# udev naming scheme
/dev/hda1 /boot ext3     sync,noatime     0 0
/dev/hda2 swap  swap     defaults,noatime 0 0
/dev/hda5 /     reiserfs defaults,noatime 0 0

Some distributions enable devfs in the kernel, but disable the CONFIG_DEVFS_MOUNT option. In that case, /dev is not automatically mounted by the kernel at boot and there will be a line in /etc/fstab like devfs /dev devfs defaults 0 0. Comment out this line by adding a ”#” to the front.

Booting the kernel

The only thing left is to tell the kernel not to use devfs. This is done by adding the defvs=nomount option to the kernel boot parameters in either /boot/grub/grub.conf or /etc/lilo.conf.

# a portion of the /boot/grub/grub.conf
title Linux 2.6 (using udev)
  root (hd0,0)
  kernel /vmlinuz26 root=/dev/hda5 ro vga=773 devfs=nomount single
title Linux 2.6 (using devfs)
  root (hd0,0)
  kernel /vmlinuz26 root=/dev/hda5 ro vga=773
# a portion of the /etc/lilo.conf file
# Linux 2.6 (using udev)
image = /boot/vmlinuz26
  append = "root=/dev/hda5 ro vga=773 devfs=nomount single"
  label = linux-devfs
# Linux 2.6 (using devfs)
image = /boot/vmlinuz26
  label = linux-devfs
  append = "root=/dev/hda5 ro vga=773"

Don't forget to run the lilo command before you reboot!!

NOTE: it is always best to reboot into single user mode when trying out a feature that is likely to break your system if not configured properly.

Did it Work?

Reboot (into single-user mode the first time!)

Depending on your distribution, you should have some sort of bootup message saying that the udev system is starting. You can verify that udev started by checking to make sure that /dev is not mounted as a devfs filesystem.

[neptune ~]$ mount 
/dev/hda5 on / type reiserfs (rw,noatime)
none on /proc type proc (rw)
none on /sys type sysfs (rw)
none on /dev/pts type devpts (rw)
none on /dev/shm type tmpfs (rw)
tmpfs on /tmp type tmpfs (rw)
/dev/hda1 on /boot type ext3 (rw,sync,noatime)
/dev/hda6 on /home type reiserfs (rw,noatime)
/dev/hdb1 on /shared type reiserfs (rw,noatime)
none on /proc/bus/usb type usbfs (rw)

A listing of the files in /dev should also give you a clue. There should only be about 90-100 files and directories in the top-level of /dev. In particular, there will only be enough /dev/hd* or /dev/sd* devices to cover the actual devices that you have attached to your system (or /dev/discs/* if you like that sort of thing).

It Worked! What Next?

One minor “gotcha” for a devfs to udev migration is that udev doesn't always create a /dev/mouse symlink for you, so if you have xorg.conf configured to use a mouse at /dev/mouse, you will either have to change xorg.conf to use the mouse device at /dev/input/mice or make a symlink from /dev/mouse to /dev/input/mice.

[neptune ~]$ cd /dev
[neptune /dev]$ ln -s input/mice mouse
[neptune /dev]$ ls -l mouse
lrwxrwxrwx  1 root root 10 2005-07-14 23:30 mouse -> input/mice

udev Tricks

USB Thumb Drive

Modifying the Config Files

Did it Work?

USB Printer

Modifying the Config Files

Did it Work?

The Future is Now (Project Utopia)

Project Utopia

Real Plug and Play

 
 
mark/linux_udev_presentation.txt · Last modified: 2006/11/21 02:42 (external edit)
 
Recent changes RSS feed Driven by DokuWiki