mirror of
https://github.com/Poltern/lfs-ru.git
synced 2024-10-19 12:10:32 +03:00
322 lines
24 KiB
XML
322 lines
24 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||
<!ENTITY % general-entities SYSTEM "../general.ent">
|
||
%general-entities;
|
||
]>
|
||
|
||
<sect1 id="ch-config-udev">
|
||
<?dbhtml filename="udev.html"?>
|
||
|
||
<title>Взаимодействие с устройствами и модулями</title>
|
||
|
||
<indexterm zone="ch-config-udev">
|
||
<primary sortas="a-Udev">Udev</primary>
|
||
<secondary>usage</secondary>
|
||
</indexterm>
|
||
|
||
<para>В <xref linkend="chapter-building-system"/>, мы установили демон udev
|
||
во время сборки <phrase revision="sysv">udev</phrase>
|
||
<phrase revision="systemd">systemd</phrase>. Прежде чем мы углубимся в детали того, как
|
||
работает udev, необходимо кратко рассказать о предыдущих методах взаимодействия с устройствами.</para>
|
||
|
||
<para>Системы Linux традиционно использовали метод статического создания устройств, при котором
|
||
огромное количество узлов устройств(иногда буквально тысячи узлов) создавалось в
|
||
<filename class="directory">/dev</filename>, независимо от того, существовали ли соответствующие
|
||
аппаратные устройства на самом деле. Обычно это делалось с помощью скрипта <command>MAKEDEV</command>,
|
||
который содержал ряд вызовов команды <command>mknod</command> с соответствующими основными и
|
||
второстепенными номерами устройств, для всех возможных вариантов, которые только могут
|
||
существовать в мире.</para>
|
||
|
||
<para>Используя метод udev, узлы устройств создаются только для тех устройств, которые
|
||
обнаружены ядром. Эти узлы устройств создаются каждый раз при загрузке системы; они хранятся
|
||
в файловой системе <systemitem class="filesystem">devtmpfs</systemitem> (виртуальная файловая
|
||
система, которая полностью находится в оперативной памяти). Узлы не занимают много
|
||
места в памяти и их общий размер незначителен.</para>
|
||
|
||
<sect2>
|
||
<title>История</title>
|
||
|
||
<para>В феврале 2000 года, новая файловая система <systemitem
|
||
class="filesystem">devfs</systemitem> была принята в ветку ядра 2.3.46 и была
|
||
доступна на протяжении выпуска стабильных релизов ветки 2.4. Хотя она и
|
||
присутствовала в ядре, такой способ динамического создания устройств никогда не
|
||
получал поддержки от разработчиков ядра.</para>
|
||
|
||
<para>Основная проблема с подходом, принятым <systemitem class="filesystem">devfs</systemitem>
|
||
была связана с обработкой обнаружения, создания и назначения имен устройствам. Проблема
|
||
связанная с именованием узлов была самой важной. Общепринято, что если имена устройств
|
||
можно настраивать, политика именования устройств должна выбираться системными администраторами,
|
||
а не навязываться разработчиками. Файловая система <systemitem class="filesystem">devfs</systemitem>
|
||
также страдала от состояния гонки, присущего её архитектуре; оно не могло быть исправлено без
|
||
существенной переработки ядра. <systemitem class="filesystem">devfs</systemitem> долгое
|
||
время была помечена как устаревшая и, наконец, была удалена из ядра в июне 2006 года.</para>
|
||
|
||
<para>При разработке нестабильной ветки ядра 2.5, позднее, выпущенной как стабильный
|
||
релиз 2.6, появилась новая виртуальная файловая система
|
||
<systemitem class="filesystem">sysfs</systemitem>. Задача этой файловой системы
|
||
заключалась в предоставление информации о конфигурации оборудования системы процессам
|
||
пользовательского пространства. С помощью этого представления, видимого в пользовательском
|
||
пространстве, стало возможным разработать замену пользовательского пространства
|
||
для <systemitem class="filesystem">devfs</systemitem>.</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Реализация Udev</title>
|
||
|
||
<sect3>
|
||
<title>Sysfs</title>
|
||
|
||
<para>Краткое описание файловой системы <systemitem class="filesystem">sysfs</systemitem> было
|
||
представлено выше. Можно задаться вопросом, как <systemitem class="filesystem">sysfs</systemitem>
|
||
получает информацию об устройствах в системе, и о том, какие номера устройств должны использоваться
|
||
для них. Драйверы, скомпилированные в ядро, регистрируют свои объекты в
|
||
<systemitem class="filesystem">sysfs</systemitem> (внутри <systemitem class="filesystem">devtmpfs</systemitem>),
|
||
по мере обнаружения ядром. Для драйверов, которые скомпилированы в виде модулей, регистрация
|
||
происходит при его загрузке. После монтирования файловой системы
|
||
<systemitem class="filesystem">sysfs</systemitem> (в каталог <filename class="directory">/sys</filename>),
|
||
данные, зарегистрированные драйверами, в <systemitem class="filesystem">sysfs</systemitem>,
|
||
станут доступны для пользовательского пространства и udevd для обработки (включая модификацию
|
||
узлов устройств).</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3 id='ch-config-udev-device-node-creation'>
|
||
<title>Создание узла устройства</title>
|
||
|
||
<para>Файлы устройств создаются ядром в файловой системе
|
||
<systemitem class="filesystem">devtmpfs</systemitem>. Любой драйвер,
|
||
которому необходимо зарегистрировать узел устройства, будет использовать для этого
|
||
<systemitem class="filesystem">devtmpfs</systemitem> (через системный драйвер ядра). Когда
|
||
экземпляр <systemitem class="filesystem">devtmpfs</systemitem> монтируется в каталог
|
||
<filename class="directory">/dev</filename>, узел устройства будет доступен в пользовательском
|
||
пространстве с фиксированным именем, разрешениями и владельцем.</para>
|
||
|
||
<para>Через некоторое время, ядро отправит uevent в <command>udevd</command>.
|
||
На основе правил, которые указанны в файлах в каталогах
|
||
<filename class="directory">/etc/udev/rules.d</filename>, <filename
|
||
class="directory">/lib/udev/rules.d</filename>, и <filename
|
||
class="directory">/run/udev/rules.d</filename>, <command>
|
||
udevd</command> создаст дополнительные символические ссылки на узлы устройств,
|
||
или сменит разрешения, владельца или группу, или изменит запись (имя) во внутренней
|
||
базе данных <command>udevd</command> для этого объекта.</para>
|
||
|
||
<para>Правила в этих трёх каталогах пронумерованы и используются совместно. Если
|
||
<command>udevd</command> не может найти правило для устройства, он оставит права
|
||
доступа и владельца на <systemitem class="filesystem">devtmpfs</systemitem>, которые
|
||
были установлены изначально.</para> </sect3>
|
||
|
||
<sect3 id="module-loading">
|
||
<title>Загрузка модуля</title>
|
||
|
||
<para>Драйверы устройств, скомпилированные в виде модулей ядра могут содержать
|
||
встроенные псевдонимы. Псевдонимы можно увидеть просмотрев вывод программы
|
||
<command>modinfo</command>, обычно они связаны со специфичными для шины идентификаторами
|
||
устройств, которые поддерживается модулем. Например, драйвер <emphasis>snd-fm801</emphasis>
|
||
подерживает PCI устройства с идентификатором поставщика 0x1319 и идентификатором
|
||
устройства 0x0801, и имеет псевдоним <literal>pci:v00001319d00000801sv*sd*bc04sc01i*</literal>.
|
||
Для большинства устройств, драйвер шины экспортирует псевдонимы драйвера, которые
|
||
будет обрабатывать устройство через <systemitem class="filesystem">sysfs</systemitem>. Например,
|
||
файл <filename>/sys/bus/pci/devices/0000:00:0d.0/modalias</filename> может
|
||
содержать строку <literal>pci:v00001319d00000801sv00001319sd00001319bc04sc01i00</literal>.
|
||
Правила по умолчанию, которые предоставлены Udev, заставят <command>udevd</command>
|
||
вызвать <command>/sbin/modprobe</command> с содержимым, которое находится в значении
|
||
переменной окружения <envar>MODALIAS</envar> uevent (которое должно совпадать с
|
||
содержимым файла <filename>modalias</filename> в sysfs), тем самым загружая все
|
||
модули, чьи псевдонимы совпадают в строке после расширения подстановочных
|
||
знаков</para>
|
||
|
||
<para>В указанном примере, это означает, что в дополнение к <emphasis>snd-fm801</emphasis>
|
||
будет загружен устаревший (и нежелательный) драйвер <emphasis>forte</emphasis>, если он
|
||
будет доступен. Ниже приведены способы, как можно предотвратить загрузку нежелательных
|
||
драйверов.</para>
|
||
|
||
<para>Само ядро также способно загружать модули для сетевых протоколов, файловых систем
|
||
и поддержки NLS по запросу.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Работа с устройствами с горячей заменой или динамическими устройствами</title>
|
||
|
||
<para>При подключении устройства, например, MP3-плеер, к универсальной последовательной
|
||
шине (USB), ядро распознает, что устройство подключено, и генерирует событие
|
||
uevent. Затем это событие обрабатывается <command>udevd</command>, как было описано выше.</para>
|
||
|
||
</sect3>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Проблемы с загрузкой модулей и созданием устройств</title>
|
||
|
||
<para>Существует несколько возможных проблем, связанных с автоматическим созданием узлов
|
||
устройств.</para>
|
||
|
||
<sect3>
|
||
<title>Модуль ядра не загружается автоматически</title>
|
||
|
||
<para>Udev загрузит модуль только в том случае, если у него есть псевдоним, специфичный
|
||
для шины, и драйвер шины правильно экспортирует необходимые псевдонимы в <systemitem
|
||
class="filesystem">sysfs</systemitem>. В других
|
||
случаях следует организовать загрузку модуля иными способами. Известно, что, начиная
|
||
с версии Linux-&linux-version;, udev, выполняет загрузку правильно написанных
|
||
драйверов для INPUT, IDE, PCI, USB, SCSI, SERIO, и FireWire устройств.</para>
|
||
|
||
<para>Чтобы определить, имеет ли требуемый драйвер устройства необходимую поддержку
|
||
Udev, запустите <command>modinfo</command> с именем модуля в качестве аргумента.
|
||
Далее, попробуйте найти каталог устройства в
|
||
<filename class="directory">/sys/bus</filename> и проверьте, есть ли там
|
||
файл <filename>modalias</filename>.</para>
|
||
|
||
<para>Если файл <filename>modalias</filename> существует в
|
||
<systemitem class="filesystem">sysfs</systemitem>, то драйвер, который поддерживает
|
||
устройство, может обращаться к нему напрямую, но не имеет псевдонима, это ошибка
|
||
в драйвере. Загрузите драйвер без помощи Udev и ожидайте, что проблема будет
|
||
исправлена позднее.</para>
|
||
|
||
<para>Если же в каталоге <filename class="directory">/sys/bus</filename> нет
|
||
файла <filename>modalias</filename>, это означает, что разработчики ядра еще не
|
||
добавили поддержку <filename>modalias</filename> к этому типу шины.
|
||
В Linux-&linux-version; это относится к шиной ISA. Ожидайте, что эта проблема
|
||
будет исправлена в более поздних версиях ядра.</para>
|
||
|
||
<para>Udev не предназначен для загрузки драйверов <quote>обёрток</quote>, таких как
|
||
<emphasis>snd-pcm-oss</emphasis> и не аппаратных драйверов, например,
|
||
<emphasis>loop</emphasis>.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Модуль ядра не загружается автоматически и Udev не предназначен для его
|
||
загрузки</title>
|
||
|
||
<para>Если модуль <quote>обёртка</quote> только расширяет функциональность,
|
||
предоставляемую каким-либо другим модулем (например модуль
|
||
<emphasis>snd-pcm-oss</emphasis> расширяет функциональность модуля
|
||
<emphasis>snd-pcm</emphasis>, давая возможность звуковым картам быть доступными
|
||
для OSS приложений), настройте <command>modprobe</command> для загрузки оболочки
|
||
после того, как Udev загрузит обернутый модуль. Для этого добавьте строку
|
||
<quote>softdep</quote> в файл, который находится в каталоге
|
||
<filename>/etc/modprobe.d/<replaceable><filename></replaceable>.conf</filename>.
|
||
Например:</para>
|
||
|
||
<screen role="nodump"><literal>softdep snd-pcm post: snd-pcm-oss</literal></screen>
|
||
|
||
<para>Обратите внимание, что команда <quote>softdep</quote> разрешает добавлять
|
||
<literal>pre:</literal> зависимости, или одновременно
|
||
<literal>pre:</literal> и <literal>post:</literal> зависимости. Обратитесь к документации
|
||
<ulink role='man' url='&man;modprobe.d.5'>modprobe.d(5)</ulink> для изучения синтаксиса и
|
||
возможностей <quote>softdep</quote>.</para>
|
||
|
||
<para revision="sysv">Если рассматриваемый модуль не является обёрткой, и полезен сам по
|
||
себе, настройте загрузочный скрипт <command>modules</command>, чтобы он инициализировался
|
||
при загрузке системы. Для этого добавьте имя модуля в файл <filename>/etc/sysconfig/modules</filename>
|
||
в отдельной строке. Этот способ сработает и для модулей-обёрток, но не является оптимальным.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Udev загружает какой-то нежелательный модуль</title>
|
||
|
||
<para>Либо не создавайте модуль, либо занесите его в черный список в файле
|
||
<filename>/etc/modprobe.d/blacklist.conf</filename>, как это сделано с
|
||
модулем <emphasis>forte</emphasis> в примере ниже:</para>
|
||
|
||
<screen role="nodump"><literal>blacklist forte</literal></screen>
|
||
|
||
<para>Модули, занесенные в черный список, можно загрузить вручную с помощью явной команды
|
||
<command>modprobe</command>.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Udev неправильно создает устройство или делает неправильную символическую ссылку</title>
|
||
|
||
<para>Это обычно происходит, если правило неожиданно совпадает с другим устройством.
|
||
Например, плохо написанное поставщиком оборудования правило может соответствовать как
|
||
диску SCSI(искомое устройство), так и универсальному устройству SCSI (неправильно).
|
||
Найдите ошибочное правило и исправьте его с помощью
|
||
команды <command>udevadm info</command>.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Правило Udev работает ненадежно</title>
|
||
|
||
<para>Это может быть проявлением предыдущей проблемы. В ином случае, если
|
||
правило использует атрибуты файловой системы
|
||
<systemitem class="filesystem">sysfs</systemitem>, то это может быть
|
||
проблемой синхронизации ядра, которая будет исправлена в более поздних
|
||
версиях ядра. Но вы можете обойти проблему, создав правило, которое
|
||
ожидает используемый атрибут <systemitem class="filesystem">sysfs</systemitem>
|
||
и добавляет его к файлу правил <filename>/etc/udev/rules.d/10-wait_for_sysfs.rules</filename>
|
||
(создайте его, если файл не существует). Пожалуйста, сообщите в списке
|
||
рассылки разработчиков LFS, если это решение вам поможет.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Udev не создаёт устройство</title>
|
||
|
||
<para>Во-первых, убедитесь, что драйвер встроен в ядро или уже загружен как модуль, и, что
|
||
udev не создает устройство с неправильным именем.</para>
|
||
|
||
<para>Если драйвер ядра не экспортирует свои данные в
|
||
<systemitem class="filesystem">sysfs</systemitem>, udev не хватает информации, необходимой
|
||
для создания узла устройства. Это, вероятнее всего, произойдет со сторонними драйверами,
|
||
которых нет в дереве исходного кода ядра. Создайте
|
||
статический узел в каталоге <filename>/usr/lib/udev/devices</filename> с
|
||
соответствующими старшим/младшим номерами (смотрите файл devices.txt
|
||
в документации к ядру или документации, предоставленной сторонним поставщиком
|
||
драйвера). Статический узел будет скопирован в
|
||
<filename class="directory">/dev</filename> с помощью <command>udev</command>.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Порядок присвоения имен устройствам меняется случайным образом после перезагрузки</title>
|
||
|
||
<para>Это связано с тем, что udev обрабатывает события uevents и загружает модули
|
||
параллельно, а значит в непредсказуемом порядке. Это никогда не будет <quote>исправлено</quote>.
|
||
Вы не должны полагаться на то что имена устройств ядра стабильны. Вместо этого создайте
|
||
свои собственные правила, которые делают символические ссылки со стабильными именами на
|
||
основе некоторых неизменяемых атрибутов устройства, таких как серийный номер или вывод
|
||
различных утилит *_id, установленных Udev. Смотрите <xref linkend="ch-config-symlinks"/> и
|
||
<xref linkend="ch-config-network"/> для примера.</para>
|
||
|
||
</sect3>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Полезная информация</title>
|
||
|
||
<para>Дополнительную документацию можно получить на следующих сайтах:</para>
|
||
|
||
<itemizedlist>
|
||
|
||
<listitem>
|
||
<para>Реализация пользовательского пространства в <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>Файловая система <systemitem class="filesystem">sysfs</systemitem>
|
||
<ulink url="https://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf"/></para>
|
||
</listitem>
|
||
|
||
<!-- No longer available
|
||
<listitem>
|
||
<para>Pointers to further reading
|
||
<ulink url="http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html"/>
|
||
</para>
|
||
</listitem>
|
||
-->
|
||
</itemizedlist>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|