FreeBSD и тачпады

Еще один интересный способ решения проблем с оборудованием в этой замечательной ОС. Будет актуально только «особенным» пользователям, действительно использующим это на ноутбуке.

Слева очередная версия Эльзы, созданная нейросетью, справа - виновник торжества.
Слева очередная версия Эльзы, созданная нейросетью, справа — виновник торжества.

Особые проблемы «особенных» пользователей

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

По крайней мере так учит Windows Drivers Kit.

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

Выгружаемая часть обычно называется «модулем ядра», но выгрузить можно далеко не все.

Помимо динамической загрузки и выгрузки, существует механизм удаления частей ядра (например отвечающих за ненужное вам оборудование) на стадии сборки — с помощью параметров, указываемых в специальном конфигурационном файле т. н. «конфиге ядра».

В былинные времена, когда сборка из исходников еще не считалась простыми пользователями Linux и BSD чем-то особенным, народ активно обменивался этими самыми конфигами.

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

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

Лотерея, лохотрон и выбор устройства

Чтобы ядро ОС могло использовать конкретную часть логики для инициализации оборудования, существует сложный многоуровневый механизм определения типа оборудования, который начинается с двух числовых кодов: «device id» и «vendor id».

Vendor ID — код производителя устройства, DeviceID — код устройства.

По идее комбинация этих двух кодов дает уникальное и однозначное определение железки, но конечно же на практике все сильно сложнее:

Обратите внимание на subvendor и subdevice - еще два дополнительных идентификатора устройства
Обратите внимание на subvendor и subdevice — еще два дополнительных идентификатора устройства

С появлением массового производства левой электроники в Китае, весь красивый и логичный механизм централизованного именования, когда за каждым производителем закреплен свой уникальный код Vendor ID — встал и вышел в окно вон.

И его больше нет с нами, аминь.

Появились дубли, поэтому примерно с начала 2000х полагаться только на DeviceID и VendorID стало фактически невозможно.

Помимо идентификаторов, разные устройства одного типа имеют еще и разные протоколы инициализации — пакеты данных, разного размера и с разными данными внутри.

Что в итоге приводит к необходимости в логике перебора — ядро натуральным образом пытается подобрать подходящий «драйвер», пуляя в железку разные пакеты инициализации и ожидая на какой она ответит:

Тот самый цикл, с
Тот самый цикл, с «угадайкой».

Обратите внимание на цикл, выделенный в центре скриншота — вот так выглядит массив с данными, по которому идет итерация:

Видите предупреждение что
Видите предупреждение что «порядок записей крайне важен»? Все также из‑за дублей в кодах и сложной логики определения.

Видите дублирующиеся коды deviceId (0×08)?

Это означает, что устройства от трех разных производителей считают себя одной семьей возвращают один и тот же deviceId.

А от четвертого производителя — нет:

Elantech — ренегаты до конца!
Elantech — ренегаты до конца!

Но это еще не все.

Практически для всех периферийных устройств существуют общепринятые и хорошо поддерживаемые стандартные протоколы взаимодействия, не привязанные к конкретному производителю.

В случае мыши, это например тот самый «Generic Mouse», которым бывает прикидывается тачпад или какая-нибудь особо навороченная модель, для которой нет официальной поддержки.

Отсутствие или пробелы в реализации «vendor specific» протоколов плюс неверное определение устройства в сумме и создают ту самую «проблему с поддержкой клиентского оборудования», от которой страдают все открытые ОС.

В качестве решения разработчики применяют самый настоящий reverse engineering, восстанавливают по крупицам работу протокола и на свет появляется функционал ядра с поддержкой нового оборудования.

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

Тот самый
Тот самый «тачпад», на который вы каждый день нажимаете.

Нормальные герои всегда идут в обход

На одном из моих ноутбуков была давняя проблема с тачпадом — он успешно определялся, но «tap to click» (нажатия по поверхности тачпада для клика) упорно не хотели работать, сколько бы я не крутил настройки.

Проблема была только в FreeBSD, в Linux на этой же машине все работало как надо.

Однажды я обнаружил вот такое сообщение в багтрекере FreeBSD:

Хотя речь про другую модель — смысл затеи не поменяется.
Хотя речь про другую модель — смысл затеи не поменяется.

Суть описанного выше метода:

удаление кодов (deviceId) устройства из списка поддерживаемых на уровне исходников ядра, для того чтобы ОС использовала стандартный протокол инициализации и работы вместо «vendor specific».

Что и было проделано, внесением правок в файл:

/usr/src/sys/dev/atkbdc/psm.c

Вот так тачпад определялся до патча:

fb8305edbe01288d84ceee542993a03d.png

А так после патча:

f2c217631ddba715337a8e867843d94c.png

После чего тачпад наконец заработал как надо и автор получил свой работающий «tap to click», чем и пользуется до сих пор.

Весь патч заключается в двух закомментированных строчках, отвечающих за инициализацию тачпада конкретной модели:

fd26d03ce84d1d3f57e4e359bbc46557.png

Разумеется ядро после этого необходимо пересобрать.

P.S.

Описанное в статье вполне применимо для всех BSD-систем, не только для одной FreeBSD, хотя конечно конкретный файл в исходниках для внесения правок будет отличаться.

В ядре Linux все сильно сложнее, но теоретически описанный подход применим и там.

Также замечу что подобным образом возможно исправить ситуацию далеко не только с тачпадом — видеокарты, аудио и множество других устройств имеют как свою специфику так и «базовый функционал», который можно попробовать включить аналогичным способом, отломав vendor-specific инициализацию.

Оригинал статьи был опубликован в октябре прошлого года в нашем блоге и все также актуален на дату публикации.

Разумеется такие правки ядра никогда не попадут в апстрим, поскольку фактически уменьшают его функционал, но описанное стоит взять на вооружение если вы действительно наслаждаетесь используете BSD‑системы в повседневной работе.

© Habrahabr.ru