середа, 25 січня 2012 р.

Linux HCL - поддерживаемое оборудование

Делаем отчёт в MS Windows - получаем ответ в Linux.
http://vasilisc.com/hcl/detect.php

Сделал первую версию статистики, в дальнейшем исправим, подрихтуем, приукрасим.
http://vasilisc.com/hcl/stats.php

Многие видели сайты, посвящённые оборудованию в Linux. Сама мысль, что информация собрана в ручную или скриптами, но так или иначе людьми, которые не поленились и отправили отчёт о своём оборудовании с указанием "работает/не работает" - всё это наводило на меня уныние.

Ведь если вдуматься, то работающее оборудование в Linux обслуживает или само ядро или модуль ядра. А мы люди опять описываем на многочисленных сайтах, то что определил наш релиз Linux, точнее его новое ядро и окружение. То есть у ядра есть своя "база данных устройств", а мы её через наш человеческий фактор выносим на сайты.

Начал интересоваться как именно Linux обслуживает мои железяки и загружает тот или иной модуль для обслуживания конкретного устройства. Здесь и далее мы будем обсуждать только "PCI устройства", иными словами "всё что расположено на материнке".

В Линуксе есть команда lspci, которая выводит информацию об вашем оборудовании и какой "модуль" обслуживает конкретный компонент.
Типа так,

03:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8101E/RTL8102E PCI Express Fast Ethernet controller [10ec:8136] (rev 01)
 Kernel driver in use: r8169
 Kernel modules: r8169
04:01.0 Ethernet controller [0200]: VIA Technologies, Inc. VT6105/VT6106S [Rhine-III] [1106:3106] (rev 86)
 Kernel driver in use: via-rhine
 Kernel modules: via-rhine

И меня терзала мысль, а как именно Линукс определяет, кто будет обслуживать устройство. В выше указанном примере сетевую карту "RTL8101E/RTL8102E PCI Express Fast Ethernet controller" будет обслуживать модуль r8169, а другую сетевую карту "VT6105/VT6106S [Rhine-III]" - модуль via-rhine.

Но они обе сетевые карты, хоть и разного производителя!
И как Linux их различает?
И как "знает" что для одной сетевой карты нужен один модуль, а для другой карты - другой модуль?

До этого момента я знал об идентификаторах оборудования, но не был силён в этой теме. Прочитав литературу, выяснилось что есть некие числа, которые определяют во-первых, класс устройства (далее Class Code - CC). То есть видеокарта это одно, а сетевая карта это другое и у них разные "числа класса устройств".

Самое главное, что есть база описывающая, какой Class Code что значит, но об этом чуть позже.

Во-вторых, есть число, которое однозначно определяет производителя железяки и называется Vendor ID. У каждого производителя своё уникальное число.
В-третьих, есть число, которое однозначно определяет саму железяку и называется Device ID. У каждой железяки своё уникальное число, НО в пределах производителя!
Есть еще числа, но мы на этом остановимся, кому интересно, то подробности в википедии в статье PCI configuration space.

И так есть 3 числа, но пока не понятно как эти числа связаны с модулями, то есть какой модуль кого будет обслуживать. Сначала я выяснил, что большинство утилит, типа lspci, пользуется базой, в которой числа расшифровываются в понятные человеку описания.

База расположена в Ubuntu Linux по адресу /usr/share/misc/pci.ids и обновляется командой update-pciids. Благодаря этой базе, можно узнать что значат те или иные числа.

Следующая моя мысль была "покопаться в исходниках lspci", ведь как-то утилита выводит обслуживающий железяку модуль! Ковыряя исходники lspci выяснилось, что lspci использует виртуальную файловую систему sysfs в Linux. Изменив чуток исходники lspci и заставив выводить путь, откуда lspci берёт имя обслуживающего модуля, я увидел картину

03:00.0 0200: 10ec:8136 (rev 01)
 Subsystem: 1462:529c
 Path to : /sys/bus/pci/devices/0000:03:00.0/driver
 Kernel driver in use: r8169

04:01.0 0200: 1106:3106 (rev 86)
 Subsystem: 1186:1403
 Path to : /sys/bus/pci/devices/0000:04:01.0/driver
 Kernel driver in use: via-rhine

То есть lspci банально читает псевдофайл driver из сконструированного пути в /sys/bus/pci/ и всё!
Линукс грузится, происходит инициализация устройств, sysfs заполняется псевдофайлами, которые описывают конкретный компьютер, а утилита lspci просто читает эти файлы ... мдаааа.
Тут я понял, что тупик! От чего ушёл, к тому и пришёл. Время потрачено зря и толку ноль.

Но где-то всё таки есть "база", какой модуль и какие "числа" обслуживает. И я нашёл её - это файл modules.pcimap.
Файл имеет следующую структуру и наполнен данными:

# pci module         vendor     device     subvendor  subdevice  class      class_mask driver_data
nvidiafb             0x000010de 0xffffffff 0xffffffff 0xffffffff 0x00030000 0x00ff0000 0x0
shpchp               0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x00060400 0xffffffff 0x0
via-rhine            0x00001106 0x00003106 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0
r8169                0x000010ec 0x00008136 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0
........

Из файла modules.pcimap многое стало ясно! Определённый "класс устройства Class Code" + "производитель Vendor" + "устройство Device" определённо указывают на модуль, который будет обслуживать.

Решено было воплотить идею на сайте в виде скрипта, которому скармливают файл отчёт об оборудовании, а он выдаёт какое устройство, каким модулем будет обслуживаться. И тут меня посетила с дружественным визитом гениальная идея - файл-отчёт нужно создавать в MS Windows!

Если человек так или иначе загрузил Linux, то он сам увидит как его оборудование поддерживается. Нужно заманивать windows пользователей! Увидев, что его оборудование отлично поддерживается в Linux, многие задумаются - "а не попробовать ли мне установить Linux?"

Вся идея, вроде, была неплоха: "делаем в винде отчёт, а получаем какой результат будет в линуксе". В MS Windows есть утилита devcon.exe, которая поможет создать нужный файл-отчёт.

Но накидав черновик на сайте, "был опечален". Все было не так радужно, как представлялось вначале. На одних и тех же компьютерах были сделаны отчёты в MS Windows с помощью devcon.exe и в Ubuntu Linux с помощью lspci. На этих отчётах сразу "нарисовалась" проблема, что не все устройства "определялись" в макете сайта, который использовал первую версию базы данных, основанной на modules.pcimap. Сейчас кажется смешным, но я не сразу понял, что есть модули, которые занимаются группой устройств и охватывают, естественно, множество VendorID и DeviceID.

Взгляните:

# pci module         vendor     device     subvendor  subdevice  class      class_mask driver_data
nvidiafb             0x000010de 0xffffffff 0xffffffff 0xffffffff 0x00030000 0x00ff0000 0x0
shpchp               0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x00060400 0xffffffff 0x0

Модуль nvidiafb занимается только видеокартами, так как класс устройства 0x00030000 - это видеокарты. Но производитель должен быть nVidia, так как 0x000010de зарезервирован за этой фирмой. А вот 0xffffffff в поле device и говорит, что устройство-видеокарта может быть любой!

Модуль shpchp (Standard Hot Plug PCI Controller Driver) занимается всеми "PCI bridge" (0x00060400). Производитель и само устройство может быть любым, так как выставлено 0xffffffff.

Улучшив скрипт, улучшилось распознавание и настроение! Зелёным цветом выводились устройства, для которых найден обслуживающий их linux модуль. Красным цветом окрашивалось не найденое и было огромное желание сделать так, чтобы красного было как можно меньше.

Многое, но не всё, находится в файле modules.pcimap, который хранит связи между устройствами и модулями. У меня мелькнула ободряющая мысль - "а в исходниках ядра linux есть то, чего нет в modules.pcimap?". Оказалось есть!
Нужно разыскивать конструкции вида

PCI_DEVICE(0x8086,0x25F0)
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185)
в файлах исходниках ядра линукс. Если в каком-то файле в дереве исходниках линукса встречается конструкция PCI_DEVICE(), значит программный код этого исходника будет обслуживать данное устройство.

Очень лениво было писать программу, которая бы обходила дерево файлов и читая, разыскивала конструкции вида PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185). Так же находила чему равно значение переменных, если вместо шестнадцатеричных чисел указана переменная, и заменяла имя переменной на её значение. Дал себе слово, что напишу позже такую программу на Питоне, а пока сваял баш-скриптик, который с помощью grep/sed и "такой-то матери" составил мне базу вида
/путь/к/файлу/модуля vendorid deviceid

И так у нас теперь "две базы". Ищем в базе "modules.pcimap", если не найден, то ищем в базе "исходники ядра линукс". К этому моменту хорошо улучшилось определение устройств.

Стало понятно, что нужно больше файлов-отчётов devcon и я решил обратиться к единомышленникам с forum.ubuntu.ru, которые очень сильно помогли, отправив мне множество различных отчётов. Какой-то период времени заняло тестирование, так как присланные отчёты показали множество моментов, которые я пропустил своими личными отчётами.

К этому времени нужно было решить что делать с устройствами к которым не нужны драйвера в полном смысле этого слова. Вывод lspci у таких устройств не показывал наличие задействованных модулей, но lspci легче! Lspci, редиска, просто читает псевдофайлы, а моему скрипту на сайте нужно что-то решить, когда в процессе разбора файла от devcon он найдёт упоминание об устройстве. Я решил добавить код, который отрабатывает когда поиск по двум базам заканчивается неудачно. Код простой, анализируется класс устройства и для таких устройств как память (0500), флеш-память (0501), контроллер памяти (0580), ISA которая теперь часть LPC Bus (0601) выводится информация, что "драйвер" не нужен.

К этому времени всё работало более-менее хорошо, нужно было делать красивую одёжку для скрипта php, так как чёрные буквы на белом фоне в 21 веке - не камильфо. Так как вебмастер из меня никакой, решил обратиться к другу, который в этом деле профи. Евгений Пашков потратил своё время и силы и создал интерфейс, который имитирует внешний вид Ubuntu, так как сайт по мимо основной задачи выполняет функцию "пропаганды дистрибутива Ubuntu среди пользователей MS Windows".

Пока Евгений ваял интерфейс, я озадачился безопасностью. Прочёл статьи о безопасном программировании в PHP и применил их на практике, всё таки есть процедура закачки файл-отчёта на сайт. Хакеры не дремлют и это нужно помнить.

Вот в принципе и всё.
В планах:
1) избавится от багов, которые вылезут при активном использовании сайта
2) написать всё таки программу для разбора исходников ядра линукс и пополнении базы
3) попробовать замахнутся на разбор и определение внешних устройств, таких как принтеры, сканеры и т.д и т.п.

АААА вот собственно и скрипт http://vasilisc.com/hcl/detect.php

Продолжение Сказка про USB устройства

Немає коментарів:

Дописати коментар

HyperComments for Blogger

comments powered by HyperComments