| 1 | <?xml version="1.0" encoding="ISO-8859-1"?>
 | 
|---|
| 2 | <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
 | 
|---|
| 3 |   "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
 | 
|---|
| 4 |   <!ENTITY % general-entities SYSTEM "../../general.ent">
 | 
|---|
| 5 |   %general-entities;
 | 
|---|
| 6 | ]>
 | 
|---|
| 7 | 
 | 
|---|
| 8 | <sect1 id="ch-scripts-udev">
 | 
|---|
| 9 |   <?dbhtml filename="udev.html"?>
 | 
|---|
| 10 | 
 | 
|---|
| 11 |   <title>Device and Module Handling on an LFS System</title>
 | 
|---|
| 12 | 
 | 
|---|
| 13 |   <indexterm zone="ch-scripts-udev">
 | 
|---|
| 14 |     <primary sortas="a-Udev">Udev</primary>
 | 
|---|
| 15 |   <secondary>usage</secondary></indexterm>
 | 
|---|
| 16 | 
 | 
|---|
| 17 |   <para>In <xref linkend="chapter-building-system"/>, we installed the Udev
 | 
|---|
| 18 |   package. Before we go into the details regarding how this works, a brief
 | 
|---|
| 19 |   history of previous methods of handling devices is in order.</para>
 | 
|---|
| 20 | 
 | 
|---|
| 21 |   <para>Linux systems in general traditionally use a static device creation
 | 
|---|
| 22 |   method, whereby a great many device nodes are created under <filename
 | 
|---|
| 23 |   class="directory">/dev</filename> (sometimes literally thousands of nodes),
 | 
|---|
| 24 |   regardless of whether the corresponding hardware devices actually exist.
 | 
|---|
| 25 |   This is typically done via a <command>MAKEDEV</command> script, which
 | 
|---|
| 26 |   contains a number of calls to the <command>mknod</command> program with
 | 
|---|
| 27 |   the relevant major and minor device numbers for every possible device that
 | 
|---|
| 28 |   might exist in the world. Using the Udev method, only those devices which
 | 
|---|
| 29 |   are detected by the kernel get device nodes created for them. Because
 | 
|---|
| 30 |   these device nodes will be created each time the system boots, they will
 | 
|---|
| 31 |   be stored on a <systemitem class="filesystem">tmpfs</systemitem> (a virtual
 | 
|---|
| 32 |   file system that resides entirely in system memory). Device nodes do not
 | 
|---|
| 33 |   require much space, so the memory that is used is negligible.</para>
 | 
|---|
| 34 | 
 | 
|---|
| 35 |   <sect2>
 | 
|---|
| 36 |     <title>History</title>
 | 
|---|
| 37 | 
 | 
|---|
| 38 |     <para>In February 2000, a new filesystem called <systemitem
 | 
|---|
| 39 |     class="filesystem">devfs</systemitem> was merged into the 2.3.46 kernel
 | 
|---|
| 40 |     and was made available during the 2.4 series of stable kernels. Although
 | 
|---|
| 41 |     it was present in the kernel source itself, this method of creating
 | 
|---|
| 42 |     devices dynamically never received overwhelming support from the core
 | 
|---|
| 43 |     kernel developers.</para>
 | 
|---|
| 44 | 
 | 
|---|
| 45 |     <para>The main problem with the approach adopted by <systemitem
 | 
|---|
| 46 |     class="filesystem">devfs</systemitem> was the way it handled
 | 
|---|
| 47 |     device detection, creation, and naming. The latter issue, that of
 | 
|---|
| 48 |     device node naming, was perhaps the most critical. It is generally
 | 
|---|
| 49 |     accepted that if device names are allowed to be configurable, then
 | 
|---|
| 50 |     the device naming policy should be up to a system administrator, not
 | 
|---|
| 51 |     imposed on them by any particular developer(s). The <systemitem
 | 
|---|
| 52 |     class="filesystem">devfs</systemitem> file system also suffers from race
 | 
|---|
| 53 |     conditions that are inherent in its design and cannot be fixed
 | 
|---|
| 54 |     without a substantial revision to the kernel. It has also been marked
 | 
|---|
| 55 |     as deprecated due to a lack of recent maintenance.</para>
 | 
|---|
| 56 | 
 | 
|---|
| 57 |     <para>With the development of the unstable 2.5 kernel tree, later
 | 
|---|
| 58 |     released as the 2.6 series of stable kernels, a new virtual filesystem
 | 
|---|
| 59 |     called <systemitem class="filesystem">sysfs</systemitem> came to be. The
 | 
|---|
| 60 |     job of <systemitem class="filesystem">sysfs</systemitem> is to export a
 | 
|---|
| 61 |     view of the system's hardware configuration to userspace processes. With
 | 
|---|
| 62 |     this userspace-visible representation, the possibility of seeing a
 | 
|---|
| 63 |     userspace replacement for <systemitem class="filesystem">devfs</systemitem>
 | 
|---|
| 64 |     became much more realistic.</para>
 | 
|---|
| 65 | 
 | 
|---|
| 66 |   </sect2>
 | 
|---|
| 67 | 
 | 
|---|
| 68 |   <sect2>
 | 
|---|
| 69 |     <title>Udev Implementation</title>
 | 
|---|
| 70 | 
 | 
|---|
| 71 |     <para>The <systemitem class="filesystem">sysfs</systemitem> filesystem
 | 
|---|
| 72 |     was mentioned briefly above. One may wonder how <systemitem
 | 
|---|
| 73 |     class="filesystem">sysfs</systemitem> knows about the devices present
 | 
|---|
| 74 |     on a system and what device numbers should be used for them. Drivers
 | 
|---|
| 75 |     that have been compiled into the kernel directly register their objects
 | 
|---|
| 76 |     with <systemitem class="filesystem">sysfs</systemitem> as they are
 | 
|---|
| 77 |     detected by the kernel. For drivers compiled as modules, this
 | 
|---|
| 78 |     registration will happen when the module is loaded. Once the
 | 
|---|
| 79 |     <systemitem class="filesystem">sysfs</systemitem> filesystem is mounted
 | 
|---|
| 80 |     (on <filename class="directory">/sys</filename>), data which the built-in
 | 
|---|
| 81 |     drivers registered with <systemitem class="filesystem">sysfs</systemitem>
 | 
|---|
| 82 |     are available to userspace processes and to <command>udev</command> for
 | 
|---|
| 83 |     device node creation.</para>
 | 
|---|
| 84 | 
 | 
|---|
| 85 |     <para>The <command>S10udev</command> initscript takes care of creating
 | 
|---|
| 86 |     these device nodes when Linux is booted. This script starts by registering
 | 
|---|
| 87 |     <command>/sbin/udevsend</command> as a hotplug event handler. Hotplug
 | 
|---|
| 88 |     events (discussed below) are not usually generated during this stage,
 | 
|---|
| 89 |     but <command>udev</command> is registered just in case they do occur.
 | 
|---|
| 90 |     The <command>udevstart</command> program then walks through the
 | 
|---|
| 91 |     <systemitem class="filesystem">/sys</systemitem> filesystem and creates
 | 
|---|
| 92 |     devices under <filename class="directory">/dev</filename> that match the
 | 
|---|
| 93 |     descriptions. For example, <filename>/sys/class/tty/vcs/dev</filename>
 | 
|---|
| 94 |     contains the string <quote>7:0</quote> This string is used by
 | 
|---|
| 95 |     <command>udevstart</command> to create <filename>/dev/vcs</filename>
 | 
|---|
| 96 |     with major number <emphasis>7</emphasis> and minor <emphasis>0</emphasis>.
 | 
|---|
| 97 |     The names and permissions of the nodes created under the <filename
 | 
|---|
| 98 |     class="directory">/dev</filename> directory are configured according to
 | 
|---|
| 99 |     the rules specified in the files within the <filename
 | 
|---|
| 100 |     class="directory">/etc/udev/rules.d/</filename> directory. These are
 | 
|---|
| 101 |     numbered in a similar fashion to the LFS-Bootscripts package. If
 | 
|---|
| 102 |     <command>udev</command> can't find a rule for the device it is creating,
 | 
|---|
| 103 |     it will default permissions to <emphasis>660</emphasis> and ownership to
 | 
|---|
| 104 |     <emphasis>root:root</emphasis>.</para>
 | 
|---|
| 105 | 
 | 
|---|
| 106 |     <para>Once the above stage is complete, all devices that were already
 | 
|---|
| 107 |     present and have compiled-in drivers will be available for use. This
 | 
|---|
| 108 |     leads us to the devices that have modular drivers.</para>
 | 
|---|
| 109 | 
 | 
|---|
| 110 |     <para>Earlier, we mentioned the concept of a <quote>hotplug event
 | 
|---|
| 111 |     handler.</quote> When a new device connection is detected by the kernel,
 | 
|---|
| 112 |     the kernel will generate a hotplug event and look at the file
 | 
|---|
| 113 |     <filename>/proc/sys/kernel/hotplug</filename> to determine the userspace
 | 
|---|
| 114 |     program that handles the device's connection. The <command>udev</command>
 | 
|---|
| 115 |     bootscript registered <command>udevsend</command> as this handler. When
 | 
|---|
| 116 |     these hotplug events are generated, the kernel will tell
 | 
|---|
| 117 |     <command>udev</command> to check the <filename
 | 
|---|
| 118 |     class="directory">/sys</filename> filesystem for the information
 | 
|---|
| 119 |     pertaining to this new device and create the <filename
 | 
|---|
| 120 |     class="directory">/dev</filename> entry for it.</para>
 | 
|---|
| 121 | 
 | 
|---|
| 122 |     <para>This brings us to one problem that exists with
 | 
|---|
| 123 |     <command>udev</command>, and likewise with <systemitem
 | 
|---|
| 124 |     class="filesystem">devfs</systemitem> before it. It is commonly
 | 
|---|
| 125 |     referred to as the <quote>chicken and egg</quote> problem. Most
 | 
|---|
| 126 |     Linux distributions handle loading modules via entries in
 | 
|---|
| 127 |     <filename>/etc/modules.conf</filename>. Access to a device node causes
 | 
|---|
| 128 |     the appropriate kernel module to load. With <command>udev</command>,
 | 
|---|
| 129 |     this method will not work because the device node does not exist until
 | 
|---|
| 130 |     the module is loaded. To solve this, the <command>S05modules</command>
 | 
|---|
| 131 |     bootscript was added to the LFS-Bootscripts package, along with the
 | 
|---|
| 132 |     <filename>/etc/sysconfig/modules</filename> file. By adding module
 | 
|---|
| 133 |     names to the <filename>modules</filename> file, these modules will be
 | 
|---|
| 134 |     loaded when the computer starts up. This allows <command>udev</command>
 | 
|---|
| 135 |     to detect the devices and create the appropriate device nodes.</para>
 | 
|---|
| 136 | 
 | 
|---|
| 137 |     <para>Note that on slower machines or for drivers that create a lot
 | 
|---|
| 138 |     of device nodes, the process of creating devices may take a few
 | 
|---|
| 139 |     seconds to complete. This means that some device nodes may not be
 | 
|---|
| 140 |     immediately accessible.</para>
 | 
|---|
| 141 | 
 | 
|---|
| 142 |   </sect2>
 | 
|---|
| 143 | 
 | 
|---|
| 144 |   <sect2>
 | 
|---|
| 145 |     <title>Handling Hotpluggable/Dynamic Devices</title>
 | 
|---|
| 146 | 
 | 
|---|
| 147 |     <para>When you plug in a device, such as a Universal Serial Bus (USB)
 | 
|---|
| 148 |     MP3 player, the kernel recognizes that the device is now connected and
 | 
|---|
| 149 |     generates a hotplug event. If the driver is already loaded (either
 | 
|---|
| 150 |     because it was compiled into the kernel or because it was loaded via
 | 
|---|
| 151 |     the <command>S05modules</command> bootscript), <command>udev</command>
 | 
|---|
| 152 |     will be called upon to create the relevant device node(s) according to
 | 
|---|
| 153 |     the <systemitem class="filesystem">sysfs</systemitem> data available in
 | 
|---|
| 154 |     <filename class="directory">/sys</filename>.</para>
 | 
|---|
| 155 | 
 | 
|---|
| 156 |     <para>If the driver for the just plugged in device is available as a
 | 
|---|
| 157 |     module but currently unloaded, the Hotplug package will load the
 | 
|---|
| 158 |     appropriate module and make this device available by creating the
 | 
|---|
| 159 |     device node(s) for it.</para>
 | 
|---|
| 160 | 
 | 
|---|
| 161 |   </sect2>
 | 
|---|
| 162 | 
 | 
|---|
| 163 |   <sect2>
 | 
|---|
| 164 |     <title>Problems with Creating Devices</title>
 | 
|---|
| 165 | 
 | 
|---|
| 166 |     <para>There are a few known problems when it comes to automatically
 | 
|---|
| 167 |     creating device nodes:</para>
 | 
|---|
| 168 | 
 | 
|---|
| 169 |     <para>1) A kernel driver may not export its data to <systemitem
 | 
|---|
| 170 |     class="filesystem">sysfs</systemitem>.</para>
 | 
|---|
| 171 | 
 | 
|---|
| 172 |     <para>This is most common with third party drivers from outside the
 | 
|---|
| 173 |     kernel tree. Udev will be unable to automatically create device nodes
 | 
|---|
| 174 |     for such drivers. Use the <filename>/etc/sysconfig/createfiles</filename>
 | 
|---|
| 175 |     configuration file to manually create the devices. Consult the
 | 
|---|
| 176 |     <filename>devices.txt</filename> file inside the kernel documentation
 | 
|---|
| 177 |     or the documentation for that driver to find the proper major/minor
 | 
|---|
| 178 |     numbers.</para>
 | 
|---|
| 179 | 
 | 
|---|
| 180 |     <para>2) A non-hardware device is required. This is most common with
 | 
|---|
| 181 |     the Advanced Linux Sound Architecture (ALSA) project's Open Sound
 | 
|---|
| 182 |     System (OSS) compatibility module. These types of devices can be
 | 
|---|
| 183 |     handled in one of two ways:</para>
 | 
|---|
| 184 | 
 | 
|---|
| 185 |     <itemizedlist>
 | 
|---|
| 186 |       <listitem>
 | 
|---|
| 187 |         <para>Adding the module names to
 | 
|---|
| 188 |         <filename>/etc/sysconfig/modules</filename></para>
 | 
|---|
| 189 |       </listitem>
 | 
|---|
| 190 |       <listitem>
 | 
|---|
| 191 |         <para>Using an <quote>install</quote> line in
 | 
|---|
| 192 |         <filename>/etc/modprobe.conf</filename>. This tells the
 | 
|---|
| 193 |         <command>modprobe</command> command <quote>when loading this
 | 
|---|
| 194 |         module, also load this other module, at the same time.</quote>
 | 
|---|
| 195 |         For example:</para>
 | 
|---|
| 196 | 
 | 
|---|
| 197 | <screen><userinput>install snd-pcm modprobe -i snd-pcm ; modprobe \
 | 
|---|
| 198 |     snd-pcm-oss ; true</userinput></screen>
 | 
|---|
| 199 | 
 | 
|---|
| 200 |         <para>This will cause the system to load both the
 | 
|---|
| 201 |         <emphasis>snd-pcm</emphasis> and <emphasis>snd-pcm-oss</emphasis>
 | 
|---|
| 202 |         modules when any request is made to load the driver
 | 
|---|
| 203 |         <emphasis>snd-pcm</emphasis>.</para>
 | 
|---|
| 204 |       </listitem>
 | 
|---|
| 205 |     </itemizedlist>
 | 
|---|
| 206 | 
 | 
|---|
| 207 |   </sect2>
 | 
|---|
| 208 | 
 | 
|---|
| 209 |   <sect2>
 | 
|---|
| 210 |     <title>Useful Reading</title>
 | 
|---|
| 211 | 
 | 
|---|
| 212 |     <para>Additional helpful documentation is available at the following
 | 
|---|
| 213 |     sites:</para>
 | 
|---|
| 214 | 
 | 
|---|
| 215 |     <itemizedlist>
 | 
|---|
| 216 |       <listitem>
 | 
|---|
| 217 |         <para remap="verbatim">A Userspace Implementation of <systemitem class="filesystem">devfs</systemitem>
 | 
|---|
| 218 |         <ulink url="http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf"/></para>
 | 
|---|
| 219 |       </listitem>
 | 
|---|
| 220 |       <listitem>
 | 
|---|
| 221 |         <para remap="verbatim">udev FAQ
 | 
|---|
| 222 |         <ulink url="http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ"/></para>
 | 
|---|
| 223 |       </listitem>
 | 
|---|
| 224 |       <listitem>
 | 
|---|
| 225 |         <para remap="verbatim">The Linux Kernel Driver Model
 | 
|---|
| 226 |         <ulink url="http://public.planetmirror.com/pub/lca/2003/proceedings/papers/Patrick_Mochel/Patrick_Mochel.pdf"/></para>
 | 
|---|
| 227 |       </listitem>
 | 
|---|
| 228 |     </itemizedlist>
 | 
|---|
| 229 | 
 | 
|---|
| 230 |   </sect2>
 | 
|---|
| 231 | 
 | 
|---|
| 232 | </sect1>
 | 
|---|