| 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">  <?dbhtml filename="udev.html"?>  <title>Device and Module Handling on an LFS System</title>  <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 Udev  package. Before we go into the details regarding how this works,  a brief history of previous methods of handling devices is in  order.</para>  <para>Linux systems in general traditionally use a static device creation  method, whereby a great many device nodes are created under <filename  class="directory">/dev</filename> (sometimes literally thousands of nodes),  regardless of whether the corresponding hardware devices actually exist. This is  typically done via a <command>MAKEDEV</command> script, which contains a number  of calls to the <command>mknod</command> program with the relevant major and  minor device numbers for every possible device that might exist in the world.  Using the Udev method, only those devices which are detected by the kernel get  device nodes created for them. Because these device nodes will be created each  time the system boots, they will be stored on a <systemitem  class="filesystem">tmpfs</systemitem> file system (a virtual file system that  resides entirely in system memory). Device nodes do not require much space, so  the memory that is used is negligible.</para>  <sect2>    <title>History</title>    <para>In February 2000, a new filesystem called <systemitem    class="filesystem">devfs</systemitem> was merged into the 2.3.46 kernel    and was made available during the 2.4 series of stable kernels. Although    it was present in the kernel source itself, this method of creating devices    dynamically never received overwhelming support from the core kernel    developers.</para>    <para>The main problem with the approach adopted by <systemitem    class="filesystem">devfs</systemitem> was the way it handled device    detection, creation, and naming. The latter issue, that of device node    naming, was perhaps the most critical. It is generally accepted that if    device names are allowed to be configurable, then the device naming policy    should be up to a system administrator, not imposed on them by any    particular developer(s). The <systemitem class="filesystem">devfs</systemitem>    file system also suffers from race conditions that are inherent in its design    and cannot be fixed without a substantial revision to the kernel. It has also    been marked as deprecated due to a lack of recent maintenance.</para>    <para>With the development of the unstable 2.5 kernel tree, later released as    the 2.6 series of stable kernels, a new virtual filesystem called <systemitem    class="filesystem">sysfs</systemitem> came to be. The job of <systemitem    class="filesystem">sysfs</systemitem> is to export a view of the system's    hardrware configuration to userspace processes. With this userspace-visible    representation, the possibility of seeing a userspace replacement for    <systemitem class="filesystem">devfs</systemitem> became much more    realistic.</para>  </sect2>  <sect2>    <title>Udev Implementation</title>    <para>The <systemitem class="filesystem">sysfs</systemitem> filesystem was    mentioned briefly above. One may wonder how <systemitem    class="filesystem">sysfs</systemitem> knows about the devices present on    a system and what device numbers should be used for them. Drivers that have    been compiled into the kernel directly register their objects with    <systemitem class="filesystem">sysfs</systemitem> as they are detected by    the kernel. For drivers compiled as modules, this registration will happen    when the module is loaded. Once the <systemitem    class="filesystem">sysfs</systemitem> filesystem is mounted (on <filename    class="directory">/sys</filename>), data which the built-in drivers    registered with <systemitem class="filesystem">sysfs</systemitem> are    available to userspace processes and to <command>udev</command> for device    node creation.</para>    <para>The <command>S10udev</command> initscript takes care of creating    these device nodes when Linux is booted. This script starts by registering    <command>/sbin/udevsend</command> as a hotplug event handler. Hotplug events    (discussed below) are not usually generated during this stage, but    <command>udev</command> is registered just in case they do occur. The    <command>udevstart</command> program then walks through the <systemitem    class="filesystem">/sys</systemitem> filesystem and creates devices under    <filename class="directory">/dev</filename> that match 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 and    permissions of the nodes created under the <filename    class="directory">/dev</filename> directory are configured according to the    rules specified in the files within the <filename    class="directory">/etc/udev/rules.d/</filename> directory. These are    numbered in a similar fashion to the LFS-Bootscripts package. If    <command>udev</command> can't find a rule for the device it is creating,    it will default permissions to <emphasis>660</emphasis> and ownership to    <emphasis>root:root</emphasis>.</para>    <para>Once the above stage is complete, all devices that were already present    and have compiled-in drivers will be available for use. This leads us to the    devices that have modular drivers.</para>    <para>Earlier, we mentioned the concept of a <quote>hotplug event    handler.</quote> When a new device connection is detected by the kernel,    the kernel will generate a hotplug event and look at the file    <filename>/proc/sys/kernel/hotplug</filename> to determine the userspace    program that handles the device's connection. The <command>udev</command>    bootscript registered <command>udevsend</command> as this handler. When    these hotplug events are generated, the kernel will tell    <command>udev</command> to check the <filename    class="directory">/sys</filename> filesystem for the information pertaining    to this new device and create the <filename class="directory">/dev</filename>    entry for it.</para>    <para>This brings us to one problem that exists with <command>udev</command>,    and likewise with <systemitem class="filesystem">devfs</systemitem> before it.    It is commonly referred to as the <quote>chicken and egg</quote> problem. Most    Linux distributions handle loading modules via entries in    <filename>/etc/modules.conf</filename>. Access to a device node causes the    appropriate kernel module to load. With <command>udev</command>, this method    will not work because the device node does not exist until the module is loaded.    To solve this, the <command>S05modules</command> bootscript was added to the    LFS-Bootscripts package, along with the    <filename>/etc/sysconfig/modules</filename> file. By adding module names to the    <filename>modules</filename> file, these modules will be loaded when the    computer starts up. This allows <command>udev</command> to detect the devices    and create the appropriate device nodes.</para>    <para>Note that on slower machines or for drivers that create a lot of device    nodes, the process of creating devices may take a few seconds to complete.    This means that some device nodes may not be immediately accessible.</para>  </sect2>  <sect2>    <title>Handling Hotpluggable/Dynamic Devices</title>    <para>When you plug in a device, such as a Universal Serial Bus (USB) MP3    player, the kernel recognizes that the device is now connected and generates    a hotplug event. If the driver is already loaded (either because it was    compiled into the kernel or because it was loaded via the    <command>S05modules</command> bootscript), <command>udev</command> will be    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>.</para>    <para>If the driver for the just plugged in device is available as a module but    currently unloaded, the Hotplug package will load the appropriate module    and make this 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 creating    device nodes:</para>    <para>1) A kernel driver may not export its data to <systemitem    class="filesystem">sysfs</systemitem>.</para>    <para>This is most common with third party drivers from outside the kernel    tree. Udev will be unable to automatically create device nodes for such    drivers. Use the <filename>/etc/sysconfig/createfiles</filename>    configuration file to manually create the devices. Consult the    <filename>devices.txt</filename> file inside the kernel documentation or    the documentation for that driver to find the proper major/minor    numbers.</para>    <para>2) A non-hardware device is required.  This is most common with    the Advanced Linux Sound Architecture (ALSA) project's Open Sound    System (OSS) compatibility module.  These types of devices can be    handled 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 role="nodump"><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 following    sites:</para>    <itemizedlist>      <listitem>        <para>A Userspace Implementation of <systemitem class="filesystem">devfs</systemitem>        <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>
 |