В Глава 8, мы установили демон udev во время сборки udev . Прежде чем мы углубимся в детали того, как работает udev, необходимо кратко рассказать о предыдущих методах взаимодействия с устройствами.
Системы Linux традиционно использовали метод статического создания
устройств, при котором огромное количество узлов устройств(иногда
буквально тысячи узлов) создавалось в /dev
, независимо от того, существовали ли
соответствующие аппаратные устройства на самом деле. Обычно это
делалось с помощью скрипта MAKEDEV, который содержал ряд
вызовов команды mknod с
соответствующими основными и второстепенными номерами устройств, для
всех возможных вариантов, которые только могут существовать в мире.
Используя метод udev, узлы устройств создаются только для тех
устройств, которые обнаружены ядром. Эти узлы устройств создаются
каждый раз при загрузке системы; они хранятся в файловой системе
devtmpfs
(виртуальная файловая
система, которая полностью находится в оперативной памяти). Узлы не
занимают много места в памяти и их общий размер незначителен.
В феврале 2000 года, новая файловая система devfs
была принята в ветку ядра 2.3.46 и была
доступна на протяжении выпуска стабильных релизов ветки 2.4. Хотя
она и присутствовала в ядре, такой способ динамического создания
устройств никогда не получал поддержки от разработчиков ядра.
Основная проблема с подходом, принятым devfs
была связана с обработкой обнаружения,
создания и назначения имен устройствам. Проблема связанная с
именованием узлов была самой важной. Общепринято, что если имена
устройств можно настраивать, политика именования устройств должна
выбираться системными администраторами, а не навязываться
разработчиками. Файловая система devfs
также страдала от состояния гонки,
присущего её архитектуре; оно не могло быть исправлено без
существенной переработки ядра. devfs
долгое время была помечена как устаревшая
и, наконец, была удалена из ядра в июне 2006 года.
При разработке нестабильной ветки ядра 2.5, позднее, выпущенной как
стабильный релиз 2.6, появилась новая виртуальная файловая система
sysfs
. Задача этой файловой системы
заключалась в предоставление информации о конфигурации оборудования
системы процессам пользовательского пространства. С помощью этого
представления, видимого в пользовательском пространстве, стало
возможным разработать замену пользовательского пространства для
devfs
.
Краткое описание файловой системы sysfs
было представлено выше. Можно задаться
вопросом, как sysfs
получает
информацию об устройствах в системе, и о том, какие номера
устройств должны использоваться для них. Драйверы,
скомпилированные в ядро, регистрируют свои объекты в sysfs
(внутри devtmpfs
), по мере обнаружения ядром. Для
драйверов, которые скомпилированы в виде модулей, регистрация
происходит при его загрузке. После монтирования файловой системы
sysfs
(в каталог /sys
), данные, зарегистрированные драйверами, в
sysfs
, станут доступны для
пользовательского пространства и udevd для обработки (включая
модификацию узлов устройств).
Файлы устройств создаются ядром в файловой системе devtmpfs
. Любой драйвер, которому необходимо
зарегистрировать узел устройства, будет использовать для этого
devtmpfs
(через системный драйвер
ядра). Когда экземпляр devtmpfs
монтируется в каталог /dev
, узел
устройства будет доступен в пользовательском пространстве с
фиксированным именем, разрешениями и владельцем.
Через некоторое время, ядро отправит uevent в udevd. На основе правил,
которые указанны в файлах в каталогах /etc/udev/rules.d
, /lib/udev/rules.d
, и /run/udev/rules.d
, udevd создаст дополнительные
символические ссылки на узлы устройств, или сменит разрешения,
владельца или группу, или изменит запись (имя) во внутренней базе
данных udevd для
этого объекта.
Правила в этих трёх каталогах пронумерованы и используются
совместно. Если udevd не может найти правило
для устройства, он оставит права доступа и владельца на
devtmpfs
, которые были
установлены изначально.
Драйверы устройств, скомпилированные в виде модулей ядра могут
содержать встроенные псевдонимы. Псевдонимы можно увидеть
просмотрев вывод программы modinfo, обычно они связаны со
специфичными для шины идентификаторами устройств, которые
поддерживается модулем. Например, драйвер snd-fm801 подерживает PCI устройства с
идентификатором поставщика 0x1319 и идентификатором устройства
0x0801, и имеет псевдоним pci:v00001319d00000801sv*sd*bc04sc01i*
. Для
большинства устройств, драйвер шины экспортирует псевдонимы
драйвера, которые будет обрабатывать устройство через
sysfs
. Например, файл
/sys/bus/pci/devices/0000:00:0d.0/modalias
может содержать строку pci:v00001319d00000801sv00001319sd00001319bc04sc01i00
.
Правила по умолчанию, которые предоставлены Udev, заставят
udevd вызвать
/sbin/modprobe с
содержимым, которое находится в значении переменной окружения
MODALIAS
uevent (которое должно
совпадать с содержимым файла modalias
в sysfs), тем самым загружая все
модули, чьи псевдонимы совпадают в строке после расширения
подстановочных знаков
В указанном примере, это означает, что в дополнение к snd-fm801 будет загружен устаревший (и нежелательный) драйвер forte, если он будет доступен. Ниже приведены способы, как можно предотвратить загрузку нежелательных драйверов.
Само ядро также способно загружать модули для сетевых протоколов, файловых систем и поддержки NLS по запросу.
При подключении устройства, например, MP3-плеер, к универсальной последовательной шине (USB), ядро распознает, что устройство подключено, и генерирует событие uevent. Затем это событие обрабатывается udevd, как было описано выше.
Существует несколько возможных проблем, связанных с автоматическим созданием узлов устройств.
Udev загрузит модуль только в том случае, если у него есть
псевдоним, специфичный для шины, и драйвер шины правильно
экспортирует необходимые псевдонимы в sysfs
. В других случаях следует организовать
загрузку модуля иными способами. Известно, что, начиная с версии
Linux-6.7.4, udev, выполняет загрузку правильно написанных
драйверов для INPUT, IDE, PCI, USB, SCSI, SERIO, и FireWire
устройств.
Чтобы определить, имеет ли требуемый драйвер устройства
необходимую поддержку Udev, запустите modinfo с именем модуля в
качестве аргумента. Далее, попробуйте найти каталог устройства в
/sys/bus
и проверьте, есть ли там
файл modalias
.
Если файл modalias
существует в
sysfs
, то драйвер, который
поддерживает устройство, может обращаться к нему напрямую, но не
имеет псевдонима, это ошибка в драйвере. Загрузите драйвер без
помощи Udev и ожидайте, что проблема будет исправлена позднее.
Если же в каталоге /sys/bus
нет
файла modalias
, это означает, что
разработчики ядра еще не добавили поддержку modalias
к этому типу шины. В Linux-6.7.4 это
относится к шиной ISA. Ожидайте, что эта проблема будет
исправлена в более поздних версиях ядра.
Udev не предназначен для загрузки драйверов «обёрток», таких как snd-pcm-oss и не аппаратных драйверов, например, loop.
Если модуль «обёртка» только расширяет функциональность,
предоставляемую каким-либо другим модулем (например модуль
snd-pcm-oss расширяет
функциональность модуля snd-pcm, давая возможность звуковым
картам быть доступными для OSS приложений), настройте
modprobe для
загрузки оболочки после того, как Udev загрузит обернутый модуль.
Для этого добавьте строку «softdep» в файл, который находится в
каталоге /etc/modprobe.d/
.
Например:
<filename>
.conf
softdep snd-pcm post: snd-pcm-oss
Обратите внимание, что команда «softdep» разрешает добавлять pre:
зависимости, или одновременно pre:
и post:
зависимости. Обратитесь к документации modprobe.d(5)
для изучения синтаксиса и возможностей «softdep».
Если рассматриваемый модуль не является обёрткой, и полезен сам
по себе, настройте загрузочный скрипт modules, чтобы он
инициализировался при загрузке системы. Для этого добавьте имя
модуля в файл /etc/sysconfig/modules
в отдельной строке. Этот
способ сработает и для модулей-обёрток, но не является
оптимальным.
Либо не создавайте модуль, либо занесите его в черный список в
файле /etc/modprobe.d/blacklist.conf
, как это сделано
с модулем forte в примере
ниже:
blacklist forte
Модули, занесенные в черный список, можно загрузить вручную с помощью явной команды modprobe.
Это обычно происходит, если правило неожиданно совпадает с другим устройством. Например, плохо написанное поставщиком оборудования правило может соответствовать как диску SCSI(искомое устройство), так и универсальному устройству SCSI (неправильно). Найдите ошибочное правило и исправьте его с помощью команды udevadm info.
Это может быть проявлением предыдущей проблемы. В ином случае,
если правило использует атрибуты файловой системы sysfs
, то это может быть проблемой
синхронизации ядра, которая будет исправлена в более поздних
версиях ядра. Но вы можете обойти проблему, создав правило,
которое ожидает используемый атрибут sysfs
и добавляет его к файлу правил
/etc/udev/rules.d/10-wait_for_sysfs.rules
(создайте его, если файл не существует). Пожалуйста, сообщите в
списке рассылки разработчиков LFS, если это решение вам поможет.
Во-первых, убедитесь, что драйвер встроен в ядро или уже загружен как модуль, и, что udev не создает устройство с неправильным именем.
Если драйвер ядра не экспортирует свои данные в sysfs
, udev не хватает информации,
необходимой для создания узла устройства. Это, вероятнее всего,
произойдет со сторонними драйверами, которых нет в дереве
исходного кода ядра. Создайте статический узел в каталоге
/usr/lib/udev/devices
с
соответствующими старшим/младшим номерами (смотрите файл
devices.txt в документации к ядру или документации,
предоставленной сторонним поставщиком драйвера). Статический узел
будет скопирован в /dev
с помощью
udev.
Это связано с тем, что udev обрабатывает события uevents и загружает модули параллельно, а значит в непредсказуемом порядке. Это никогда не будет «исправлено». Вы не должны полагаться на то что имена устройств ядра стабильны. Вместо этого создайте свои собственные правила, которые делают символические ссылки со стабильными именами на основе некоторых неизменяемых атрибутов устройства, таких как серийный номер или вывод различных утилит *_id, установленных Udev. Смотрите Раздел 9.4, «Управление устройствами» и Раздел 9.5, «Настройка сети» для примера.
Дополнительную документацию можно получить на следующих сайтах:
Реализация пользовательского пространства в devfs
http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf
Файловая система sysfs
https://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf