linux-video-drv

внутри пентаграммы: Linux/xBSD/NVIDIA/ATI/Matrox

крис касперски, ака мыщъх, no-email

совсем недавно ситуация с видео-драйверами под Linux/xBSD была поистине критической — официальных драйверов не существовало, энтузиасты кололи бинарные Windows-дрова, пытаясь хоть как-то заставить их работать их под никсами. теперь же, ведущие производители видео-карт для большинства своих моделей предлагают драйвера для Linux, а в отдельных случаях и для xBSD, вот только качество этих самих драйверов далеко не на высоте и без танцев с бубном при их установке не обойтись…

Никсовая модель разработки драйверов радикально отличается от принципов системного программирования под Windows. Зоопарк UNIX-подобных систем требует совершенно иных подходов, вовлекающих в процесс разработки драйвера создателей самой операционной системы, без поддержки которых драйвер обречен на загнивание.

При всем многообразии Windows-систем (драйверная модель которых многократно менялась даже в рамках линейки NT), их количество хоть и велико, но конечно, а всякая система дана нам в виде законченного набора двоичных модулей, обладающих вполне предсказуемыми свойствами. В никсах же все зыбко, здесь ни на что нельзя положиться или опереться. Продвинутый пользователь может скомпилировать монолитное ядро без поддержки модульности (а это значит, что драйвера должны быть представлены в виде исходных текстов, включенных в общее дерево ядра), системные вызовы варьируются от системы к системе, поддерживают множество моделей перехода с прикладного уровня на уровень ядра (далекий вызов по селектору 07h, прерывание 80h, машинная команда SYSENTER) и так же допускают изменения соглашения о передаче параметров — через стек или регистры…

UNIX-сообщество не прилагает существенных усилий для облегчения жизни сторонним создателям драйверов, препятствуя распространению закрытых бинарных драйверов, работающих только под той версий UNIX'а для которой они были созданы. UNIX way это — открытые тексты, адоптируемые создателями дистрибутивов с учетом всех, внесенных ими изменений в код ядра, высокоуровневым библиотекам-оберткам вокруг системных вызовов и т. д. Таким образом, при всем нежелании коммерческих разработчиков расставаться с исходными текстами, другого пути попросту нет, а всякие попытки обойти фундаментальные особенности UNIX-систем рождают монстров, от которых не в восторге ни составители дистрибутивов, ни конечные пользователи.

Но довольно слов! Пора браться за дело! Рассмотрим какие подходы исповедуют ведущие разработчики: ATI, NVIDIA, Matrox и чем они порочны.

Рисунок 1 сравнительный размер видео-драйверов от различных производителей

Это не драйвера, а гигантские циклопические сооружения, занимающие в упакованном виде порядка ~50 Мбайт, что создает определенные проблемы даже для пользователей ADSL, не говоря уже о Dial-Up модемах. Это не драйвера, а черт знает что! Нет, не знает, иначе бы уже давно повесился на своем хвосте!

И что же находится внутри этого чуда инженерной мыслис расширением .run? Оказывается, файл представляет собой короткий shell-скрипт к которому дописан gzip-архив, проверяемый на предмет целостности этим самым скриптом, с последующей распаковкой и передачей управления на пусковой файл, если проверка прошла успешно.

Рисунок 2 ассортимент Linux-драйверов от ATI

При желании run-файл можно распаковать и руками. Грузим его в любой hex-редактор, находим последовательность «1F 8B 08 00», выделяя блок отсюда и до EOF, сохраняем его на диск, меняя расширение на .gz, натравливаем на это дело gzip (или любой другой совместимый с ним архиватор), извлекаем оттуда .tar, который и разворачиваем на диске со всей иерархией директорий, что там имеется.

В «корневом» каталоге архива находится огромное количество .sh-файлов из которых нас в первую очередь интересуют ati-installer.sh, postun_drv.sh, post_drv.sh иpre_drv.sh, отвечающие за определение версии системы, сборку и установку драйверов.

Сами же драйвера поставляются в виде «полуфабриката» — откомпилированных so-библиотек, расположенных в каталогах /x710, /x690, /x680 (для 32-разрядных версий) и /x710_64a, /x690_64a, /x680_64a (для 64-разрядных версий). Как легко видеть, за этими «магическими» цифрами скрывается модель видео-карты (и, в зависимости от типа драйвера, эти цифры могут варьироваться в очень широких пределах), однако, по любому, пихать в один архив драйвера для разных видео-карт не есть хорошо, тем более, что каждый из каталогов (а их у нас шесть) в неупакованном виде тянет на десяток мегабайт.

Рисунок 3 внешний вид автоматического установщика видео-драйвера от ATI

Дальше начинается самое интересное. «Полуфабрикаты» собираются на конечной машине, линкуясь при помощи стандартного линкера «ld», который обязан там быть (в дистрибутивах, заточенных под начинающего пользователя, его обычно нет). При этом возникает проблема определения версий стандартных библиотек (типа LIBC) и путей к ним, решаемая в данном случае эвристическим путем, реализованным в процедуре DetectLIBC (см. файл ati-installer.sh содержащей довольно много ошибок).

Парни из ATI (судя по всему) не знают, что линковать модули можно не только с помощью линкера, но и… компилятора GCC, который уж точно знает какие библиотеки у нас установлены и где их искать. Впрочем, на целевой машине GCC может и не быть, так что подход разработчиков в чем-то оправдан. Нарвавшись на ошибку линкера, ругающегося на ненайденные библиотеки/пути, продвинутые пользователи всегда могут заглянуть в вышеупомянутые скрипты, пофиксив проблему вручную.

Системно-зависимый код вынесен в директорию /packages, из которой следует, что в настоящий момент ATI поддерживает следующие дистрибутивы: /Debian, /Fedora, /Mandriva, /RedFlag, /RedHat, /Slackware, /SuSE и /Ubuntu, отличающееся друг от друга главным образом абсолютными путями и «родимыми пятнами» (например, в Ubuntu это способ запуска программ из-под root'а). Все системно-зависимые файлы представлены в текстовой форме (скрипты) и при возникновении терок с конкретным дистрибутивом, они сравнительно легко правятся более или менее продвинутым пользователем. Кстати говоря, обращает на себя интернациональный состав разработчиков драйвера. Комментарии к скрипту для /Slackware написаны на французском языке, остальные — на английском.

«Полуфабрикаты», собираемые на целевой машине (при всех минусах такой схемы), — это большой шаг вперед для инженеров из ATI. Раньше было еще хуже. Возле ссылки на драйвер красуется горделивой примечание: «Notes: The above drivers support English only. The display driver requires POSIX shared memory to be enabled on the system. Kernel Source package is no longer required if Kernel Header package is installed», из которого следует, что теперь установщику требуются лишь заголовочные файлы, а не полные тексты ядра, которые зачастую отсутствуют даже на девелоперских машинах!!!

И при всем этом, библиотеки-полуфабрикаты, изначально закладываются на вполне конкретные архитектурные особенности, что ухудшает их совместимость с нестандартными ядрами, не говоря уже про то, что от ядра требуется поддержка модульности (упрощающая внедрение rootkit'ов) и вообще, гарантий, что драйвер встанет с пол-пинка, у нас нет никаких. И стоило ради этого качать 50 метров?!

Сабжевая фирма так же использует run-формат (для Linux систем) и простой gzip-архив (для FreeBSD), каждый из которых занимает ~13 Мбайт, что намного лучше, чем у ATI. К тому же в комплект поставки входит довольно подробная документация в формате man и html, в неупакованном виде занимающая ~1 Мбайт с описанием возможных проблем и путей их решения. На этом благопристойности, собственно говоря, и заканчиваются. Дальше начинается сплошной мрак.

Рисунок 4 ассортимент Linux/xBSD видео-драйверов от NVIDIA

Каталог /usr/src вместо исходных текстов содержит заголовочные файлы, двоичный загружаемый модуль ядра nv-kernel.o и предкомпилированные бинарники, специфичные для каждой конкретной версии Linux'а, засунутые в каталог /usr/src/precompiled, в частности, дистрибутив RedHat'анасчитывает 78 версий. Другие дистрибутивы — чуть меньше, но проблема ведь не в количестве, а в самом факте наличия системно-зависимых файлов, представляющие собой обычные объектные модули в ELF-формате, слегка искореженные разработчиками, впендюривших свой логотив перед ELF-заголовком и, чтобы «скормить» файл дизассемблеру, необходимо открыть его в hex-редакторе, найти строку «ELF», выделив блок до EOF и сохранив его в нормальный объектный модуль, который теперь можно хачить, исправляя ошибки разработчиков, после чего проделать обратную операцию, вернув заголовок на место.

Во Free-BSD драйвере каталога /precompiled, естественно нет, поскольку, Free-BSD она одна (зоопарка клонов здесь нет), точнее, это парни из NVIDIA думают, что она одна, забывая о различных версиях и нестандартных ответвлениях, не говоря уже за Open-BSD в которой все совсем по другому и Net-BSD, портированную под рекордное число различных процессорных платформ. Самое смешное, что даже во Free-BSD-версии драйвера присутствует множество «не вычищенного» Linux-кода.

Несмотря на то, что качество NVIDIA-драйверов намного выше, чем у ATI (NVIDIA учитывает многие неочевидные тонкости ядра), с совместимостью у них дела обстоят просто кошмарно. Драйвер либо становится автоматом, либо не становится вообще и чтобы заставить его работать, необходимо сменить версию Linux'а (Free-BSD) или, при наличии опыта, попытаться захачить двоичные файлы, разобраться в которых _намного_ труднее, чем в текстовых скриптах от ATI.

Вывод: при всей моей антипатии к ATI (со вкусами не спорт, это дело личное и можно даже сказать — интимное) лучше все-таки скачать 50 Метров всякого мусора, чем ковыряться в двоичных файлах от NVIDA, рискуя потерять совместимость при обновлении версии ядра. С другой стороны, если драйвер от NVIDIA работает, то он работает, а не глючит, что довольно частенько случается с продукцией от ATI. Короче, здесь как и везде, имеется проблема выбора наименее худшего из двух отстойных.

Компания Matrox, прозванная в народе «Матрасом» (которой мыщъх оставался верным на протяжении последних десяти лет), максимально приближена к философии UNIX'а, однако, в настоящее время, не выдержав конкуренции в бытовом секторе, она сосредоточилась на промышленном (в частности, поставляя видео-карты для медицинского оборудования), что положительно сказалось на качестве кода.

Рисунок 5 ассортимент Linux видео-драйверов от Matrox'а (Free-BSD не заявлена явно, но подразумевается)

Размер gzip-архива с драйверами составляет всего ~3 Мбайта. Рядом лежит архив с полным набором «честных» исходных текстов — чуть больше 2 Мбайт. Красота да и только! (Особенно для обладателей Dial-Up каналов). К тому же, наличие сорцов позволяет пофиксить любые ошибки (одна из которых заключается в попытке повторного освобождения уже освобожденной памяти, обнаруженная мыщъхем в ходе разборов спонтанно возникающих глюков). Исходные тексты (не без переделок, конечно) могут быть встроены непосредственно в ядро, откомпилированное без поддержки модульности, плюс, поддержкой новых (или древних) версий может заниматься любой энтузиаст, а не только компания-производитель и для этого совершенно необязательно копаться в двоичном коде.

Рисунок 6 полноценные исходные тексты видео-драйверов от Matrox'а

В конце концов, Matrox производит и продает видео-карты, а не программное обеспечение. Какой смысл зажимать исходные тексты, если там все равно нет ничего интересного, а все ноу-хау со всеми прочими тайнами давно запатентованы?! К тому же, выдрать ноу-хау (если предположить, что такое там имеется) не такая уж сложная и дорогостоящая задача.

Впрочем, мы отвлеклись. Вернемся к нашим баранам. Точнее, к матрасу, достоинства которого на этом и заканчиваются. Предоставляя исходные тексты, компания не заботиться о поддержке зоопарка Linux-систем, перекладывая решений этой задачи на плечи конечного пользователя. В readme файле прямо так и написано, что мы используем абсолютные пути из Red Hat Linux 9.0, а если у вас они отличаются (как, например, в Ubuntu), то… берите исходные тексты и правьте их самостоятельно или создавайте символьные ссылки в своей файловой системе. Короче, делайте, что хотите, только не трогайте нас!

Но пути — это ладно. Исправить их минутное дело. Хуже то, что Matrox поддерживает ограниченное количество версий X'ов, в частности, драйвер для видео-карт G200/G400/G450/G550 работает только с X.org версий 6.7.0, 6.8.0, 6.8.1, 6.8.2, 6.9.0 и 7.0.0, а все прочие уже требуют довольно радикальной правки исходных текстов (и, соответственно, опыта разработки драйверов для Linux/BSD), а, учитывая невысокую популярность продукции Matrox на массовом рынке, этим никто за просто так заниматься не будет. Разве только при установке Matrox на промышленное оборудование, вокруг которого крутятся огромные деньги и туссуется множество грамотных специалистов. Впрочем, «пионеров» тоже хватает (как и в любом секторе индустрии).

В идеале, всякий нормальный дистрибутив Linux'а уже должен включать в себя надлежащим образом собранные видео-драйвера для всего «железа», которое только есть. От пользователя требуется всего лишь внимательно изучить перечень поддерживаемого оборудования, выбрав одну из упомянутых там видео-карт.

В реальной жизни все намного сложнее. Составители дистрибутивов грешат тем, что заявляют о поддержке железа без какого либо тестирования последнего. Оно и понятно. Скромный бюджет разработчиков Linux'а не может позволить им приобретать все подряд, а потому, разработчикам «фирменных» драйверов приходится верить на слово, что приводит к неизбежному накоплению ошибок. Мы думаем, что драйвер поддерживает такую-то видео-карту на данном дистрибутиве, когда в действительности он нет.

Еще хуже, если составители дистрибутива вообще не включают в него никаких закрытых драйверов, не желая нарушать целостность концепции открытых исходных текстов (а, за исключением Matrox'а, все остальные видео-драйвера —распространяются в виде закрытых двоичных моделей).

ОК, драйвер скачен, но его установка проваливается или же новые графические режимы и возможности акселерации остаютсянезадействованными. Что делать?! Самое простое — забросить Linux, вернувшись на Windows (где таких проблем просто нет), ведь если человеку нужен графический десктоп (со всякими там графическими акселераторами и эффектами прозрачности), это значит, что в философию Linux'а он не вкурил и ему нужна еще одна Windows, только не такая как у соседа, а намного более крутая. Что мешает работать в VESA-режиме и псевдотекстовом консольном режиме, поддерживаемом всеми видео-картами без исключения?!

Если же все-таки хочется графических наворотов, что ж! Первым делом следует внимательно прочитать руководство по установке драйвера (установив пакет программ для разработчика и заголовочные файлы ядра, если они не были установлены ранее), затем изучить on-line справку и faq по установке ссылка на которое обычно находится рядом с драйвером. В 9 из 10 случаев там содержится либо решение проблемы, либо некий work around («обходной» путь). Наконец, можно обратиться в отдел поддержки, подробно описав ситуацию (только не стоит ждать быстрого ответа) или немного погуглить в Сети.

Гарантий, что проблема имеет решение, естественно, нет никаких. Особенно, если пытаться подружить передовую модель видео-карты с древней версией Linux'а (впрочем, равно как и наоборот). Скорее всего, нам предложат сменить систему или карту, что не всегда приемлемо, но… UNIX-системы всегда славились своей «дружелюбностью» к потребителям.

На каком же вендоре все-таки стоит остановить свой выбор? Вопрос неоднозначен и зависит от специфики решаемой задачи. В критических инфрастуктурах (или домашнем компьютере, владелец которого каждую перезагрузку которого ощущает чуть ли не как физическую боль) лучше всего использовать видео-карты от Matrox (если только их удастся найти), однако, прежде чем драйвера встанут в строй, над исходными текстами придется пыхнет не одну ночь. Зато мы получим именно то, что нам нужно (например, монолитное ядро, рекомендуемое к использованию в серверах). Без опыта программирования драйверов под Linux/FreeBSD за Matrox лучше всего даже не браться (за исключением тех случаев, когда заданная конфигурация явным образом поддерживается драйвером).

ATI – это «микрорайон», состоящий из большого количества сборных домиков, построенных в стиле: не нравится — пересобери сам. Количество поддерживаемых дистрибутивов довольно велико и потому править скрипты вручную приходится лишь относительно небольшому числу «счастливцев», обладающих «не той» версией Linux/FreeBSD, однако, установка драйвера по любому требует инструментов разработки и заголовочных файлов ядра, отсутствующих во многих дистрибутивах, что существенно увеличивает объем скачиваемых файлов, а трафик, он, как известно, денег стоит, даже на безлимите, потому как время — такие же деньги, как и все остальное.

NVIDIA вызывает довольно противоречивые чувства. Качество драйверов намного выше, чем у ATI (но ниже, чем у Matrox), количество поддерживаемых версий Linux'а так же будет повыше, чем у ATI, однако, если текстовые скрипты ATI позволяют справится с проблемой, что называется «на лету» без отрыва от распития пива из кружки с надписью «root», то захачить двоичные файлы, «заботливо» предоставленные NVIDIA сможет только продвинутый хакер, да и то не без матюгов.

Короче, нет в мире совершенства. У каждого бренда свои проблемы. Идеального производителя не существует и поддержка Linux'а (не говоря уже за BSD-подобные системы) по прежнему представляет собой огромную головную боль, частично снимаемую армадами хакеров и продвинутых пользователей, но до полностью автоматической установки драйвера, производителям еще далеко.

Ожесточенная конкуренция положительно сказывается на ассортименте и качестве UNIX-драйверов, однако, кто первым выпустит «правильный» драйвер остается только гадать. Если отбросить Matrox, то ATI больше ориентирована на опытных пользователей, а NVIDIA – на «домохозяек» или мега-хакеров, способных разобраться в двоичном коде.