О поддержке оборудования «на пальцах»
1 Апрель 2009 г
Пусть название этой заметки никого не введёт в заблуждение: «на пальцах» — вовсе не обозначает «для чайников». Более того, я считаю, что сам по себе вопрос поддержки оборудования вообще никогда не должен возникать у людей, использующих IBM PC в качестве игровой приставки, мультимедийного центра, печатной машинки и т.п. Компьютерами, по сути, является множество вещей, которыми мы пользуемся, но только для IBM PC стараниями одной очень богатой корпорации, оказывается необходимым какое-то программное обеспечение, какие-то драйвера, кодеки, руководства по «пляскам с бубном» и прочая чушь.
Заманчивая бизнес-идея продавать обывателю вычислители общего назначения, а затем сводить их с помощью программного обеспечения к тем или иным бытовым устройствам себя оправдала. Как бизнес-идея, я имею в виду. Денег заработано — «немерено». В остальном же, истинное удовольствие от общения с IBM PC под управлением одной очень дружественной ОС испытывает довольно небольшое число людей. Разумеется, всем нам нравится использовать некое устройство, не обременяя себя сколько-нибудь существенными знаниями и умениями. Но только подросток может быть счастлив от того, что это же устройство оказывается ещё и средством удовлетворения такой естественной в его возрасте подвижности рук и ума. Остальные — жалуются. На сложность, ненадёжность, вирусы и прочие неприятности, являющиеся всего лишь издержками использования универсального устройства для реализации ограниченного, в общем-то, набора функций.
Так вот, по моему скромному мнению, все вышеупомянутые категории пользователей должны быть освобождены от каких-либо знаний по поводу того, как вычислительная система поддерживает то или иное оборудование. Вовлечение их в процесс обеспечения этой поддержки (в форме предложений загрузить драйвер, принять решение об использовании в отсутствие сертификата, выбрать альтернативные опции) приводит, в лучшем случае, к формированию у этих пользователей абсолютно неадекватных представлений о действительности (вплоть до уверенности в необходимости драйвера для коврика мыши), а в худшем — к комплексам неполноценности, депрессии и прочим неприятностям вплоть до шизофрении.
Но есть существенно меньшая часть пользователей, которым знания по этому поводу могут пригодиться. Это, с одной стороны, разработчики и те, кто использует IBM PC в нетрадиционном, с точки зрения «чистого пользователя», качестве (может показаться странным, но IBM PC тоже может «считать и управлять»), а с другой — специалисты, обеспечивающие этим самым «чистым пользователям» беспроблемное существование (такова уж сложившаяся практика). Инсталлятор ОС должен сам разбираться с оборудованием, но как быть, если требуется установка на устройство, о существовании которого создатели инсталлятора даже не догадывались? Инсталляция копированием? Ошибка инсталляции (все мы — люди), мало ли? Вот тогда-то и возникает потребность узнать: а что там внутри?
Истоки
Проблемы с поддержкой оборудования случаются в любой ОС. В ms windows эти проблемы большей частью переложены на производителей устройств (список оборудования, поддерживаемого собственно windows, довольно скромен), а в linux — это проблема ядра. Корни различий — в архитектуре этих ОС да ещё в том, что «linux» — понятие собирательное. Мало того, что эта ОС работает на множестве аппаратных платформ, но даже в пределах х86 каждый волен собрать собственное уникальное ядро. И — собирают. А разработать и приложить к устройству «драйвер», который был бы способен интегрироваться с любым ядром, могут позволить себе только такие «монстры» рынка, как nVidia или AMD.
Популярные дебаты «windows vs. linux» в рамках этой темы бессмысленны: кто станет оспаривать выгоды константного ядра для изделий «ширпотреба»? Но, с другой стороны, кому нужна ОС, которую нельзя запустить на другой платформе или в специальном устройстве? Так что оставим дебаты любителям самоутверждаться в on-line дискуссиях и перейдём к «нашим баранам». То есть — к оборудованию.
К делу
Ограничимся архитектурой IBM PC, которая для всех работающих на этой платформе ОС, разумеется, одна и та же. Поскольку обещано «на пальцах», то, не вдаваясь в подробности, скажем, что главная для нас шина — PCI, а из всех нюансов спецификации последней нас будет интересовать только способность PCI-устройств идентифицировать себя набором 32-х битных численных констант: идентификаторами (id) поставщика (vendor) и устройства (device), иногда уточняемыми константами subvendor, subdevice и т. п.
Именно на этих циферках и базируется соотнесение устройств и соответствующего ПО, именуемого обычно драйвером. Не удивительно, в общем-то… Предположить, что слова «Tornado», «Diamond» или «Storm» ориентированы на покупателя, а для компьютера предпочтительнее численное выражение, было бы естественно. Именно на предмет этих циферок вам предстоит «гуглить» Сеть, если инсталляция не «случилась» автоматически.
Как увидеть эти идентификаторы в windows, я описать не берусь: традиционные трудности вербального представления пресловутого интуитивно-понятного интерфейса. Так, что ли: Мой Компьютер — Свойства — Оборудование — Диспетчер устройств — Устройство — Свойства — Сведения — Коды (id) оборудования? В linux — попроще:
lspci -nn
Вышеупомянутая lspci — программа, не отягощённая десятками опций. Так что набрать ‘man lspci‘ можно смело. А вспомнить нужный ключик всегда поможет ‘lspci --help‘. Версии lspci могут различаться, набор ключей — тоже. Если в вашей нет ключа ‘-nn‘ (numbers&names), то сначала можно определить идентификатор устройства в «дереве» PCI (lspci), а затем — его собственные идентификаторы (lspci -n). Короче: пробуйте.
Итак, устройство себя идентифицирует однозначно, осталось выяснить: какой драйвер ему нужен. Для windows идентификаторы устройства обязательно будут присутствовать в соответствующем inf-файле (поиск его в составе какого-нибудь self-extracting архива или набора cab-ов сам по себе может оказаться неординарной задачей, но это уже ваши проблемы). А для того, чтобы узнать, поддерживается ли данное устройство конкретным ядром, потребуется файл /lib/modules/XXXXXX/modules.pcimap (где XXXXXX — релиз ядра). Воспользуетесь вы любимым редактором или grep-ом — дело вкуса. Если строка с искомыми идентификаторами в файле найдена — ядро устройство поддерживает. Первое слово строки — и есть нужный модуль (драйвер).
В том же каталоге может пригодиться файл modules.deps. Найдите в нём «вычисленный» модуль, и узнаете: какие ещё модули требуются для его работы. Может пригодиться, если будете компоновать initrd или какую-нибудь микросборку сами.
Не лишней также может оказаться команда ‘modinfo имя_найденного_модуля‘. Может оказаться, что у модуля есть опции загрузки.
Если поиск в modules.pcimap оказался безрезультатным, имеет смысл повторить его в файле /usr/share/pci.ids (иногда: /usr/share/hwdata/pci.ids). По крайней мере, узнаете точное имя производителя и устройства. Нужный модуль в вашем ядре от этого не образуется, но возможности поиска в Сети — расширятся.
Есть альтернативная возможность, заключающаяся в использовании какого-нибудь rescue-livecd. Обновляется большинство из них чаще, чем универсальные дистрибутивы. Ядро, как правило, используется самое свежее, поддержка оборудования, как следствие, на самом высоком уровне. Так что если злополучное устройство работает из-под livecd (но не работает в целевой системе), то достаточно набрать ‘lspci -k‘, чтобы определить какой именно модуль его обслуживает. Если ваша lspci не знает ключа ‘-k‘, а ядро ветки 2.6, то в вашем распоряжении каталог /sys в котором тоже можно найти всю необходимую информацию. Искать нужно в подкаталоге bus/pci/devices/NNNNNN, где NNNNNN — тот самый PCI-идентификатор устройства, который вы определили с помощью lspci. Файл driver будет символической ссылкой именно на используемый модуль. Для целевой системы останется только обновить ядро (если дело только в версии) или скомпилировать нужный модуль (если такой модуль для вашей конфигурации ядра отсутствует).
При этом нужно учитывать одно обстоятельство: описанным в предыдущем параграфе способом вы определяете модуль из состава ядра livecd. То есть, если ядра livеcd и целевой системы существенно отличаются по возрасту, то не исключена ситуация, когда модуль, доступный для одного ядра, в другом просто отсутствует. Бывает, что поддержку одного и того же устройства в одной версии ядра обеспечивает один модуль, а в другой — совсем иной. В общем: не соскучишься.
Особенности автоматической загрузки нужных модулей при старте целевой системы — опускаем. Во-первых: потому, что их несколько. А во-вторых: потому, что они «дистрибутиво-специфичны». На крайний случай, в вашем распоряжении всегда есть ‘modprobe’, которую никто не помешает вам вставить в какой-нибудь из скриптов загрузки.
Зачем?
Правомерный вопрос. Абсолютному большинству пользователей — незачем. Но если вы готовите систему для записи в ПЗУ, копируете файловую систему для использования на другом оборудовании или делаете ещё что-нибудь, когда ни о каком инсталляторе речь не идёт, то — понадобится.
Отдельная история — использование initrd (initial ram disk — стартовая файловая система в памяти). Когда-то она требовалась почти исключительно при наличии в системе SCSI-устройств, драйвера которых, как правило, в образ ядра не входили, а загружались как модули. Новые файловые системы, широкое использование usb-устройств и вытеснение SATA-контроллерами своих IDE-предшественников реанимировали интерес к initrd. Теперь это почти неотъемлемая часть большинства инсталляций. По умолчанию в initrd включаются модули поддержки файловых систем и usb (одному Богу известно, почему образ ядра не поддерживает файловую систему, предлагаемую инсталлятором по умолчанию, но — оставим это на совести составителей дистрибутивов). А вот модули SATA-контроллеров могут отсутствовать.
Инсталляция в этом случае, как правило, заканчивается генерацией initrd (обычно, команда ‘mkinitrd‘), которая определяет, какие модули нужны для обеспечения доступа к корневой файловой системе, и включает их в initrd. Предпринимаемый mkinitrd анализ сродни описанному выше. В результате имеем универсальные ядро и набор модулей, но «индивидуализированную» initrd. Совершенно очевидно, что обновлению копированием (или перезаписью ПЗУ) должна предшествовать генерация соответствующей целевой системе initrd.
Как ни странно, но представления о PCI-устройствах могут оказаться нужными и под windows. Потеря инсталляционных дисков, отказ от Vista в пользу XP (или наоборот), могут оставить вас наедине с этой ОС практически без драйверов. Прекрасная возможность оценить, насколько хорошо ms windows поддерживает оборудование. Искать рекомендуется всё по тем же Vendor_id:Device_id. Не исключено, что устройство удастся «оживить» только с «чужим» драйвером. Спасибо, что хоть такую возможность M$ нам оставила.
Практически всё сказанное справедливо и в отношении usb-устройств. Аналогичные команды, аналогичные файлы. Только подставляйте ‘usb‘ вместо ‘pci‘.
«Тернии»
Не без этого. Если бы не было трудностей, то работа инсталляторов была бы безукоризненной. А это, к сожалению, не так. «Есть многое на свете, друг Горацио…», как сказал когда-то один датский принц.
Во-первых, в мире open source вполне естественно наличие нескольких разработчиков, занятых обеспечением поддержки одного и того же устройства. Они могут не знать о существовании друг друга, исходить из принципиально разных требований, исповедовать разные принципы конструирования. Результат: два и более драйвера для одного устройства. Разумеется, ядро не потерпит неоднозначности. Одной паре Vendor_id:Device_id будет поставлен в соответствие совершенно определённый модуль (см. modules.pcimap), только вот лучший ли… Не стоит абсолютно полагаться на авторитет «ядерщиков» и уж тем более составителей дистрибутивов. Никогда не будет лишним знать о назначении blacklist-ов в каталоге /etc/modprobe.d. И не такая уж редкость, когда «не кошерный» ndiswrapper окажется предпочтительнее «родного» bcm43xx, например.
Во-вторых, современное оборудование всё чаще не является «вещью в себе». Для работы ему может потребоваться загрузка прошивки (firmware). И вовсе не жадность заставляет производителей предлагать такие решения. Современная электроника живуча настолько, что запросто переживает релизы протоколов и стандартов. А менять коммуникационное оборудование вслед за каждым усовершенствованием протокола — по меньшей мере, глупо. Вот и в составе IBM PC всё больше устройств, для которых производитель предусмотрел загрузку микрокода. Вышеупомянутый модуль bcm43xx (поддержка wi-fi адаптеров серии 43ХХ от Broadcom) как раз и предполагает такую загрузку. Модуль-то предполагает, да не всякий дистрибутив включает в себя эту самую прошивку. А некоторые забывают приложить ещё и программу загрузки. При этом модуль исправно загружается в память в соответствии с всё тем же modules.pcimap. Воистину: «очень похож на настоящий, но — не работает».
В-третьих, драйвер — это модуль в linux и файл.sys (с сопутствующими dll-ками и описателем — файл.inf) в windows. Но никак не многомегабайтный exe-шник с документацией на всех мыслимых (и не мыслимых) языках и кучей всевозможного софта. Упаковка всего необходимого для использования определённого оборудования в единый пакет — рациональное действие. Для производителя оборудования, который прилагает к нему и ПО. Но не нужно ждать подобного от «ядерщиков» linux. Сопутствующий софт, который в некоторых случаях потребуется обязательно, будет указан в документации к модулю. А вот позаботился или нет о его наличии составитель дистрибутива… Если позаботился, то в штатных ситуациях вы просто не узнаете о том, какое дополнительное ПО потребовалось для использования wi-fi адаптера, pcmcia-карты, камеры или сканера. Но мы-то говорим о ситуациях нештатных, не так ли? Так что на несколько более профессиональном уровне без каталога /Documentation из состава дистрибуции ядра часто не обойтись. Ещё один источник информации — файлы Kconfig, содержащие, среди прочего, help-ы, предлагаемые к прочтению при конфигурировании ядра.
В-четвёртых, это так называемые win-устройства — ущербные создания, часть работы которых выполняет процессор системы под управлением опять же специального ПО, которое (бывает) написано только под windows. Ситуация, кстати, не так безнадёжна, как это было лет пять назад. Если устройство того стоит, то способ использовать его в linux, скорее всего, найдётся. Научились использовать кодеки и ndis-драйвера, написанные для win, — почему бы не использовать «недоношенный» win-принтер? Если он того стоит, разумеется.
Всё, кажется…
В Ubuntu папка — /usr/share/hwdata
Ссылки в тему:
http://pci-ids.ucw.cz/read/PC/ — по pci-устройствам
https://usb-ids.gowdy.us/read/UD/ — по usb-устройствам