Ключевые слова:udev, device, driver, hardware, linux, usb, scanner, (найти похожие документы)
From: MooSE <webmaster@ylsoftware.com.>
Date: Sun, 5 Nov 2007 17:02:14 +0000 (UTC)
Subject: Управление аппаратными средствами в Linux с помощью udev
Оригинал: http://ylsoftware.com/?action=news&na=viewfull&news=88http://ylsoftware.com/?action=news&na=viewfull&news=94
Оригинал на английском:
http://www.enterprisenetworkingplanet.com/nethub/article.php/3635686http://www.enterprisenetworkingplanet.com/nethub/article.php/3637076
В былые времена администраторы Linux имели статический каталог /dev.
Это было очень не гибко, 99% того что там содержалось было не верным.
Но мы любили этот путь. Мы не возражали против использования makedev с
различным ключами прежде чем начать использование устройства. Мы в
ручную удаляли удаляли тысячи не нужных записей, потому что настоящие
администраторы любят всё делать сами. Поскольку только такой путь
позволяет нам лучше понимать систему. Проходили годы и мы копили
бесчисленные байты знаний, чтобы потом говорить новичкам - "РТФМ,
Лузер!".
Потом появилась devfs, которая пыталась заменить эту громоздкую
систему чем-то более лёгким и простым. Создатель devfs Ричард Гуч имел
радикальную идею: в /dev должны содержаться только имеющиеся в системе
устройства, а управление должно быть максимально простым и
эффективным.
через некоторое время с гор спустился ещё один безбородый пророк -
Грэг Кроа-Хартман. Он дал ещё одну /dev-систему, названную udev.
Начиная с ядра 2.6.13 devfs больше не включён в основную ветвь ядра.
До сих пор не прекращаются дебаты "devfs против udev", о которых вы
можете читать на самых разных ресурсах. Вы всё ещё имеете /etc/devfs в
своей системе, и устройства, зависящие от этого. Например - драйвера
NVIDIA. Так что когда вы видите devfs - не думайте что сможете легко
от него избавиться.
udev также решает задачу обнаружения устройств (совместно с hal и
hotplug) и создания нодов для них в /dev. На самом деле все
устройства, даже жёсткие диски и PCI-карты, рассматриваются как
съёмные устройства. "О нет", скажете вы, "это не хорошо, потому что
тогда устройства при каждой загрузке получают новые имена".
Это не проблема. udev позволяет вам назначать статические имена
устройствам, на подобие того, как вы прописываете строки в /etc/fstab.
Наверняка ваш дистрибутив Linux идёт с уже готовой конфигурацией,
которая назначает статические имена определённым устройствам, таким
как жёсткие диски, сетевые карты и проч.
udev очень красивая и гибкая система, и когда он сконфигурирована
правильно (например поставщиком вашего дистрибутива) - ваша жизнь -
сплошное удовольствие.
Сожалею, Дэйв, однако я не могу позволить тебе сделать это
Обратная сторона этой медали - молодость всего проекта. Если вы что-то
хотите сделать то может не оказаться документации, и вам придётся
искать человека, который уже решал эту задачу. Но давайте не будем о
грустном, а лучше рассмотрим udev подробнее.
Итак. Мы всё ещё имеет каталог /dev, однако больше не является
статическим. Он заполняется нодами при загрузке. Причём ноды
генерируются в соответствии с соответствующими правилами udev.
Правила udev хранятся в файлах конфигурации, расположенных в
/etc/udev.d. Различные дистрибутивы могут изменять это местоположение.
Например в Fedora и Ubuntu есть файл /etc/udev/udev.conf, который
содержит основные опции программы, а все правила лежат в
/etc/udev/rules.d.
Каталог /sys - двоюрдный брат каталога /proc. Только он хорошо
организован, а не превращён в кашу. Туда экспортируется информация от
ядра в читабельном для человека виде. Для /proc используется файловая
система /proc, а для /sys - sysfs. Вы можете увидеть это в выводе
команды mount:
# mount
proc on /proc type proc (rw)
/sys on /sys type sysfs (rw)
udev on /dev type tmpfs (rw)
Обратите внимание на то что для /dev используется tmpfs. Что приводит
к потере всей информации оттуда при перезагрузке.
Как вы можете заметить (find /sys -type l), /sys наполнена симлинками.
Вы можете просматривать /sys как и любую другую папку, поймёте ли вы
её содержимое - другой вопрос. Но попытаться понять конечно не
помешает.
Поскольку sysfs, так же как и /proc - виртуальная файловая система -
она не занимает физического пространства. Konqueror на моей системе
говорит что она занимает 129.4, но du говорит совсем другое:
$ du -sh /sys
0 /sys
Написание правил udev
Текущие версии udev идут с man-страницами и несколькими полезными
командами. В системах на основе Debian содержимое пакета udev можно
просмотреть командой:
$ dpkg -L udev
В системах на основе RedHat (например Fedora) используйте команду:
$ rpm -ql udev
Набор команд будет зависеть от дистрибутива, однако есть команды,
одинаковые для всех дистрибутивов.
Первым делом, перед написанием правила udev, вы должны убедиться что
ядро видит ваше устройство, для которого будет применено это правило.
Для этого используйте udevinfo. Пример команды, формирующей дамп всех
устройств в базе udev:
$ udevinfo -e
Вы можете также запросить информацию об отдельных устройствах, если
знаете путь к ним. Например для разделов SATA:
$ udevinfo -a -p /block/sda/sda1
Как узнать путь к устройству? Используя udevinfo. Вы же знаете
название некоторых устройств? Вот оттуда вы и сможете получить путь:
$ udevinfo -q all -n sda
Обе эти команды дают море информации. Вы ради развлечения можете
выполнить lspci посмотреть совпадут ли значения disk/by-path/pci
полученные при помощи udevinfo:
0000:00:0f.0 RAID bus controller: VIA Technologies, Inc.
VIA VT6420 SATA RAID Controller (rev 80)
S: disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0-part1
Вывод udevinfo порой бывает очень странным, поэтому его следует
сравнивать с выводом других команд. Для USB-устройств это будет lsusb,
а для устройств SCSI это будет lsscsi
Часть 2
В этой части будет рассмотрено написание правил udev для USB-устройств.
Заставляем сканер работать правильно
Сканеры и многофункциональные принтеры/копиры не работают в Linux "из
коробки". Так что давайте совершим небольшую экскурсию с целью
заставить их работать. Для примера мы возьмём Epson Stylus CX4800. (Не
потому что это хорошая машина, а потому что она у меня есть. Он
работает на удивительных скоростях и использует специальные чернил в
виде комка, похожего на сгусток крови. Когда они случайно забивают
носики печати - он сам их очищает. Бриллиант, не правда ли?)
Прежде всего убедитесь что ваше устройство поддерживается в Linux.
Если это не так - даже udev не сможет вам помочь. Проверьте
sane-project.org и Google перед покупкой устройства.
Посмотрите у себя файл /etc/udev/rules.d/*-libsane-rules. Естественно
что в разных дистрибутивах этот файл может называться по разному. В
Kubuntu это 45-libsane.rules, в RedHat - 60-libsane.rule. Число в
начале - приоритет файла с правилами. Файлы с меньшими приоритетами
анализируются первыми. Пример *-libsane-rules:
SUBSYSTEM!="usb_device", ACTION!="add", GOTO="libsane_rules_end"
# Hewlett-Packard|ScanJet 4100C
SYSFS{idVendor}=="03f0", SYSFS{idProduct}=="0101", MODE="664", GROUP="scanner"
# Hewlett-Packard|PhotoSmart S20
SYSFS{idVendor}=="03f0", SYSFS{idProduct}=="0102", MODE="664", GROUP="scanner"
# Hewlett-Packard|ScanJet 4200C
[...]
Кажется довольно нелепым что udev делая грандиозную работу, всё же
наполняет /dev некоторым количеством неверных нодов. В любом случае
достаточно просто удалить лишние ноды.
Убедитесь что у вас установлен SANE. Подключите сканер к компьютеру и
выполните следующую команду:
# sane-find-scanner
# sane-find-scanner will now attempt to detect your scanner
[...]
found USB scanner (vendor=0x04b8, product=0x0819) at libusb:003:002
# Your USB scanner was (probably) detected. It may or may not be supported by
# SANE. Try scanimage -L and read the backend's manpage [...]
Теперь попробуйте выполнить scanimage -L под простым пользователем.
Если не получится - повторите тоже самое от имени пользователя root:
# scanimage -L
device `epson:libusb:003:002' is a Epson Unknown model flatbed scanner
В сообщение говориться о проблеме с правами доступа к сканеру. На
самом деле это не проблема. Для начала отредактируйте
/etc/sane.d/epson.conf, чтобы иметь правильно сконфигурированный
сканер. Закомментируйте все строчки кроме двух:
usb
usb 0x4b8 0x0819
Откуда берутся эти шестнадцатиричные значения? Из вывода команды
sane-find-scanner. Впишите корректные значения, а затем добавьте в
/etc/udev/rules.d/*-libsane-rules следующуе
#epson stylus cx4800
SYSFS{idVendor}=="04b8", SYSFS{idProduct}=="0819", MODE="664", GROUP="scanner"
Фактически это банальный копи-паст строчек из начала файла. Начальные
нули можно удалить.
В первой части было описано как получить уникальный ID из /sys для
испоьзования в правилах udev. Вот то, как выглядит наш Epson:
$ udevinfo -a -p /class/usb_device/usbdev3.2
follow the "device"-link to the physical device:
looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.2/usb3/3-6':
BUS=="usb"
ID=="3-6"
DRIVER=="usb"
SYSFS{configuration}=="USB2.0 MFP_Hi-Speed_"
SYSFS{devnum}=="2"
SYSFS{idProduct}=="0819"
SYSFS{idVendor}=="04b8"
SYSFS{manufacturer}=="EPSON"
SYSFS{product}=="USB2.0 MFP_Hi-Speed_"
SYSFS{serial}=="L84010507120939390"
SYSFS{speed}=="480"
SYSFS{version}==" 2.00"
Вот и всё. Сохраните изменения, перезагрузитесь и - вуаля! Вы больше
не должны заходить как root чтобы использовать ваш сканер.
SANE поставляется с огромным количеством страниц man, которые помогут
вам настроить ваш сканер. Команда man sane покажет вам их список.
Владельцы и права доступа. Имена и симлинки
Конфигурация udev оперирует тремя основными понятиями: права и
владельцы, имена, симлинки. Kubuntu раскидывает эти настройки по трём
различным файлам: 20-names.rules, 40-permissions.rules, и
60-symlinks.rules. В RedHat они не разделены на категории таким
образом. Все настройки хранятся в файле 50-udev.rules. Вы можете
редактировать его, или создать свой, например 50-udev.rules.
Когда вы хотите изменить права доступа то вам нужно проверить
/etc/udev/rules.d и убедиться что вы имеет соответствующие правила.
Легче всего для этого использовать grep. Пример поиска правил для
дисковых устройств:
$ grep -ir 'group="disk"' /etc/udev
/etc/udev/rules.d/40-permissions.rules:SYSFS{removable}!="1", GROUP="disk"
/etc/udev/rules.d/40-permissions.rules:KERNEL=="raw1394", GROUP="disk"
Этот пример показывает имя файла и найденную строку. Вы можете так же
добавить ключ -B 5 для просмотра ещё и пяти предыдущих строк, или -A 5
для просмотра последующих пяти строк.
Устройства с постоянными именами
Linux проделал большой путь. Сейчас он поддерживает множество
устройств. Обратная сторона этой медали - неустойчивые имена
устройств. Ваш дистрибутив скорее всего идёт с заранее определёнными
именами устройств для жёстких и компакт-дисков, но такие устройства
как карты USB-Flash или сетевые карты USB всё ещё не имеют
фиксированных имён.
Для решения этой проблемы есть два способа. Можно добавить другое
название или создать симлинк. Например мой второй жёсткий диск
/dev/sda является SATA-диском на 300 гигабайт, и используется мной для
хранения архива фотографий. Я могу создать файл 10-local.rules
следующего содержания:
# nickname for /dev/sda
KERNEL=="sda", NAME="photo-archives"
После перезагрузки будет устройство /dev/photo-archives. Я могу
использовать его как обычный жёсткий диск. Например я могу написать в
/etc/fstab строчку с использованием /dev/photo-archives.
Конечно это быстро и просто, но иногда лучше создать симлинк, который
будет указывайть на оригинальный нод устройства. В таком случае не
придётся искать в /etc/udev.d чтобы вспомнить реально имя устройства
если я его забуду. Запустите udevinfo и посмотрите на информацию об
устройстве:
$ udevinfo -a -p /block/sda
[...]
device '/sys/block/sda' has major:minor 8:0
looking at class device '/sys/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
SYSFS{dev}=="8:0"
SYSFS{range}=="16"
SYSFS{removable}=="0"
SYSFS{size}=="156301488"
[...]
Затем выберите один или несколько признаков и создайте правило для
симлинка:
# nickname for /dev/sda
KERNEL=="sda", SYSFS{size}=="156301488", SYMLINK+="photo-archives"
Если вы используете несколько признаков одновременно - следите чтобы
они харакетризовали одно устройство. Следите за пунктуацией. значения
KERNEL и SYSFS называются ключами соответствия, и должны использовать
знак равенства ==. SYMLINK - ключ назначения. Знак "плюс" говорит о
том что нужно "добавить симлинк", а знак равенства указывает имя этого
симлинка. Если вы пропутите "плюс" то вы удалите все уже имеющиеся
силинки.
Я для страховки использую размер, так как это единственный диск такого
размера в системе. Если любой ключ соответствия изменится - правило не
будет работать.
После перезагрузки вы обнаружите новый симлинк:
$ ls -l /dev/photo-archives
lrwxrwxrwx 1 root root 3 2006-10-09 22:19 /dev/photo-archives -> sda
Настройка сетевых карт USB
Обычным сетевым картам PCI Ethernet имена даются при помощи ifrename
на Debian-системах, или посредством методов конфигурации на RedHat.
Сетевыми картами USB всё по другому, но не сложнее. Всё что вам нужно
- MAC адрес вашей сетевой карты. Дальше легко написать правило.
Например для беспроводного адаптера:
KERNEL=="wlan*", SYSFS{address}=="00.11.22.33.44.55", NAME="wlan0"
Вы не обязаны использовать wlan0. Вы можете использовать любое другое
название, которое вам нравиться. Только не забудьте его:)
Вы можете использовать /sbin/ifconfig -a или udevinfo для получения
MAC-адреса:
$ udevinfo -a -p /sys/class/net/wlan0
Все сетевые интерфейсы находятся в /sys/class/net/.
Применение изменений udev
В Kubuntu вам необходима перезагрузка для применения новых правил. В
RedHat можно применить новые правила и без перезагрузки. Просто
выполните:
# udevcontrol reload_rules
# udevstart
Это всё. Однако имейте ввиду что udev ещё очень молод, и потому нам
хотелось бы видеть более удобные инструментальные средства для работы
с ним. Будет очень хорошо если пользователи помогут создавать их.