| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 | <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [  <!ENTITY % general-entities SYSTEM "../general.ent">  %general-entities;]><sect1 id="ch-scripts-udev"><title>Device and Module Handling on an LFS System</title><?dbhtml filename="udev.html"?><indexterm zone="ch-scripts-udev"><primary sortas="a-Udev">Udev</primary><secondary>usage</secondary></indexterm><para>In <xref linkend="chapter-building-system"/>, we installed the Udevpackage.  Before we go into the details regarding how this works,a brief history of previous methods of handling devices is inorder.</para><para>Linux systems in general traditionally use a static devicecreation method, whereby a great many device nodes are created under<filename class="directory">/dev</filename> (sometimes literallythousands of nodes), regardless of whether the corresponding hardwaredevices actually exist. This is typically done via a<command>MAKEDEV</command> script, which contains a number ofcalls to the <command>mknod</command> program with the relevant major and minor devicenumbers for every possible device that might exist in the world. Usingthe udev method, only those devices which are detected by the kernelget device nodes created for them. Because these device nodes will becreated each time the system boots, they will be stored on a<systemitem class="filesystem">ramfs</systemitem> (a file system thatresides entirely in memory and does not take up any disk space).Device nodes do not require much disk space, so the memory that isused in negligable.</para><sect2><title>History</title><para>In February 2000, a new filesystem called <systemitemclass="filesystem">devfs</systemitem> was merged into the 2.3.46kernel and was made available during the 2.4 series ofstable kernels.  Although it was present in the kernel source itself,this method of creating devices dynamically never receivedoverwhelming support from the core kernel developers.</para><para>The main problem with the approach adopted by <systemitemclass="filesystem">devfs</systemitem> was the way it handleddevice detection, creation, and naming. The latter issue, that ofdevice node naming, was perhaps the most critical. It is generallyaccepted that if device names are allowed to be configurable, thenthe device naming policy should be up to a system administrator, notimposed on them by any particular developer(s). The <systemitemclass="filesystem">devfs</systemitem> file system also suffers from raceconditions that are inherent in its design and cannot be fixedwithout a substantial revision to the kernel. It has also been markedas deprecated due to a lack of recent maintenance.</para><para>With the development of the unstable 2.5 kernel tree, laterreleased as the 2.6 series of stable kernels, a new virtual filesystemcalled <systemitem class="filesystem">sysfs</systemitem> came to be.The job of <systemitem class="filesystem">sysfs</systemitem> is toexport a view of the system's structure to userspace processes.  Withthis userspace visible representation, the possibility of seeing auserspace replacement for <systemitemclass="filesystem">devfs</systemitem> became much morerealistic.</para></sect2><sect2><title>Udev Implementation</title><para>The <systemitem class="filesystem">sysfs</systemitem> filesystemwas mentioned briefly above.  One may wonder how <systemitemclass="filesystem">sysfs</systemitem> knows about the devices presenton a system and what device numbers should be used.  Drivers thathave been compiled into the kernel directly register their objectswith <systemitem class="filesystem">sysfs</systemitem> as they aredetected by the kernel.  For drivers compiled as modules, this willhappen when the module is loaded.  Once the <systemitemclass="filesystem">sysfs</systemitem> filesystem is mounted (on<filename class="directory">/sys</filename>), the data which thebuilt-in drivers registered with <systemitemclass="filesystem">sysfs</systemitem> are available to userspaceprocesses and to <command>udev</command> for device node creation.</para><para>The <command>S10udev</command> initscript takes care of creatingthese device nodes when Linux is booted. This script starts withregistering <command>/sbin/udevsend</command> as a hotplug event handler.Hotplug events (discussed below) should not be generated during thisstage, but <command>udev</command> is registered just in case they dooccur.  The <command>udevstart</command> program then walks throughthe <systemitem class="filesystem">/sys</systemitem> filesystem andcreates devices under <filename class="directory">/dev</filename> thatmatch the descriptions.  For example,<filename>/sys/class/tty/vcs/dev</filename> contains the string<quote>7:0</quote> This string is used by <command>udevstart</command>to create <filename>/dev/vcs</filename> with major number<emphasis>7</emphasis> and minor <emphasis>0</emphasis>.  The names andpermissions of the nodes created under the<filename class="directory">/dev</filename> directory are configured accordingto the rules specified in the files within the<filename class="directory">/etc/udev/rules.d/</filename> directory.  These arenumbered in a similar fashion to the LFS bootscripts.  If<command>udev</command> can't find a rule for the device it is creating, it willdefault permissions to <emphasis>660</emphasis> and ownership to<emphasis>root:root</emphasis>.</para><para>Once the above stage is complete, all devices that were alreadypresent and have compiled-in drivers will be available for use. What about those devices that have modular drivers?</para><para>Earlier, we mentioned the concept of a <quote>hotplug eventhandler.</quote> When a new device connection is detected by thekernel, the kernel will generate a hotplug event and look at the file<filename>/proc/sys/kernel/hotplug</filename> to find out theuserspace program that handles the device's connection.  The<command>udev</command> initscript registered <command>udev</command>as this handler. When these hotplug events are generated, the kernelwill tell <command>udev</command> to check the <filenameclass="directory">/sys</filename> filesystem for the informationpertaining to this new device and create the <filenameclass="directory">/dev</filename> entry for it.</para><para>This brings us to one problem that exists with<command>udev</command>, and likewise with <systemitemclass="filesystem">devfs</systemitem> before it. It is commonlyreferred to as the <quote>chicken and egg</quote> problem.  Most Linuxdistrubtions handle loading modules via entries in<filename>/etc/modules.conf</filename>. Access to a device node causesthe appropriate kernel module to load.  With <command>udev</command>,this method will not work because the device node does not exist untilthe module is loaded.  To solve this, the<command>S05modules</command> bootscript was added to thelfs-bootscripts package, along with the<filename>/etc/sysconfig/modules</filename> file.  Byadding modulenames to the <filename>modules</filename> file, these modules will beloaded when the computer is starting up. This allows<command>udev</command> to detect the devices and create theappropriate device nodes.</para><para>Note that on slower machines or for drivers that create a lotof device nodes, the process of creating devices may take a fewseconds to complete. This means that some device nodes may not beimmediately accessible.</para></sect2><sect2><title>Handling Hotpluggable/Dynamic Devices</title><para>When you plug in a device, such a Universal Serial Bus (USB) MP3 player, the kernelrecognizes that the device is now connected and generates a hotplugevent. If the driver is already loaded (either because it was compiledinto the kernel or because it was loaded via the<command>S05modules</command> bootscript), <command>udev</command> willbe called upon to create the relevant device node(s) according to the<systemitem class="filesystem">sysfs</systemitem> data available in<filename class="directory">/sys</filename>.  If the driver for thejust plugged in device is available as a module but currently unloaded,then attaching the device to the system will only cause the kernel'sbus driver to generate a hotplug event that notifies userspace of thenew device connection and it not being attached to a driver. Ineffect, nothing happens and the device itself is not usableyet.</para><para>If building a system that has a lot of drivers compiled asmodules rather than directly built into the kernel, using the<command>S05modules</command> may not be practical. The Hotplugpackage (see <ulink url="http://linux-hotplug.sourceforge.net/"/>) canbe beneficial in these cases. When the Hotplug package is installed,it will respond to the aforementioned kernel's bus driver hotplugevents. The Hotplug package will load the appropriate module and makethis device available by creating the device node(s) for it.</para></sect2><sect2><title>Problems with Creating Devices</title><para>There are a few known problems when it comes to automatically creatingdevices nodes:</para><para>1) A kernel driver may not export its data to <systemitemclass="filesystem">sysfs</systemitem>.</para>   <para>This is most common with third party drivers from outside thekernel tree.  These drivers will not end up having their device nodescreated.  Use the<filename>/etc/sysconfig/createfiles</filename> configuration file tomanually create the devices. Consult the<filename>devices.txt</filename> file inside the kernel documentationor the documentation for that driver to find the proper major/minornumbers.</para><para>2) A non-hardware device is required.  This is most common withthe Advanced Linux Sound Architecture (ALSA) project's Open SoundSystem (OSS) compatibility module.  These types of devices can behandled in one of two ways:</para><itemizedlist><listitem><para>Adding the module names to<filename>/etc/sysconfig/modules</filename></para></listitem><listitem><para>Using an<quote>install</quote> line in<filename>/etc/modprobe.conf</filename>. This tells the<command>modprobe</command> command <quote>when loading this module, also load this other module, at the same time.</quote>  For example:</para><screen><userinput>install snd-pcm modprobe -i snd-pcm ; modprobe \    snd-pcm-oss ; true</userinput></screen><para>This will cause the system to load both the<emphasis>snd-pcm</emphasis> and <emphasis>snd-pcm-oss</emphasis>modules when any request is made to load the driver<emphasis>snd-pcm</emphasis>.</para></listitem></itemizedlist></sect2><sect2><title>Useful Reading</title><para>Additional helpful documentation is available at the followingsites:</para><itemizedlist><listitem><para>A Userspace Implementation of devfs<ulink url="http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf"/></para></listitem><listitem><para>udev FAQ<ulink url="http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ"/></para></listitem><listitem><para>The Linux Kernel Driver Model<ulink url="http://public.planetmirror.com/pub/lca/2003/proceedings/papers/Patrick_Mochel/Patrick_Mochel.pdf"/></para></listitem></itemizedlist></sect2></sect1>
 |