Как включить Bluetooth * автоматически при загрузке * для последних чипсетов Intel и Broadcom, полагающихся на btattach?

Некоторые последние чипсеты Bluetooth от Intel и Broadcom должны запускать команду btattach в пользовательском пространстве для правильной работы Bluetooth (она «присоединяет» чипсет BT и запускает загрузку необходимой прошивки, если это необходимо).

В качестве примера можно привести набор микросхем Broadcom BCM43241 rev B5, который можно найти на планшетах Lenovo ThinkPad 8, для которых требуется следующая команда # btattach --bredr /dev/ttyS1 -P bcm но это применимо ко многим другим чипсетам Bluetooth, подключенным к контроллеру UART.

В: Каков наилучший рекомендуемый способ запуска команды btattach во время загрузки, если Bluetooth включен автоматически ?

PS Идея заключалась в том, чтобы внести такую ​​модификацию в дистрибутивы Linux, которые начали упаковывать команду btattach (например, Debian), так как сейчас многие новейшие устройства просто не имеют Bluetooth, работающего из коробки. Это было бы особенно полезно для планшетов, у которых нет или нескольких полноразмерных USB-портов.

Обсуждения в списке рассылки linux-bluetooth предложили создать соответствующее udev rule , ср. это сообщение .

Для конкретного набора микросхем, упомянутого в вопросе, простое правило udev выглядит так:

$ cat /etc/udev/rules.d/98-bluetooth-attach-broadcom.rule KERNEL=="BCM2E55:00", RUN+="/usr/bin/btattach --bredr /dev/ttyS1 -P bcm"

с BCM2E55: 00, являющимся аппаратным идентификатором ACPI соответствующего набора микросхем Bluetooth, появляющимся как дочерний элемент узла устройства ttyS1 (видимый через sysfs in /sys/devices/platform/80860F0A:00/tty/ttyS1/device/BCM2E55:00$ ). Каждый идентификатор ACPI должен быть добавлен в файл правила с соответствующим / dev / ttyS *, адаптированным для каждого варианта набора микросхем.

Однако известным ограничением этого простого подхода является то, что он работает только на короткий промежуток времени, как описано здесь . Действительно, команда btattach убивается несколько секунд / минут позже. Это документированное поведение udev :

Запуск демона или других длительных процессов не подходит для udev; раздвоенные процессы, отдельные или нет, будут безоговорочно убиты после завершения обработки событий. `

Поэтому вместо запуска команды btattach непосредственно из правила udev , другим параметрам необходимо btattach косвенно btattach чтобы убедиться, что он не убит, например, через службу systemd.

Этот простой ответ по-прежнему может быть полезен в то же время при выполнении некоторых первых тестов, особенно для поиска правильного условия (состояния) правила udev.

Рабочий подход заключается в создании службы hardcoded systemd, которая выглядит так:

$ cat /etc/systemd/system/btattach.service [Unit] Description=Start btattach, needed to enable Bluetooth for some UART-based Bluetooth chipsets [Service] Type=simple # A delay is needed though, 1s seems enough on my system ExecStartPre=/bin/sleep 1s ExecStart=/usr/bin/btattach --bredr /dev/ttyS1 -P bcm [Install] WantedBy=multi-user.target`

Чтобы включить эту новую службу, выполните следующую команду:

# systemctl --system enable btattach

Перезагрузка планшета показывает, что команда btattach теперь корректно выполняется при загрузке:

$ ps auxw | grep btattach root 2059 0.0 0.0 6372 720 ? Ss 23:17 0:00 /usr/bin/btattach --bredr /dev/ttyS1 -P bcm

и Bluetooth действительно включен и работает! Настройки Gnome Bluetooth перечисляют подключенные и отсканированные устройства и запускают $ bluetoothctl из командной строки, правильно отображая контроллер.

Удивительно, но при удалении начальной команды ожидания 1s sleep используется для простое выполнение реальной команды, Bluetooth не работает вообще и не включен должным образом, несмотря на то, что btattach все еще работает правильно в списке фоновых процессов.

Не уверен, чтобы понять, что происходит совсем точно: на карту поставлена ​​проблема срочности и, конечно же, необходимая зависимость для ожидания, прежде чем предполагается запустить btattach

Более изысканный подход заключается в создании правила udev , запускаемого только при наличии подходящего оборудования, для запуска необходимой команды btattach из systemd service . Это объединяет понятия двух предыдущих ответов.

Для конкретного набора микросхем, упомянутого в вопросе, правило udev выглядит просто так:

$ cat /etc/udev/rules.d/99-bluetooth-btattach.rules KERNEL=="BCM2E55:00", RUN+="/bin/systemctl --no-block start btattach-broadcom-ttyS1.service"

с BCM2E55: 00 является аппаратным идентификатором ACPI соответствующего набора микросхем Bluetooth.

Служба systemd, совместимая только с наборами микросхем, которые появляются как дочерние узлы устройства ttyS1 (видимые через sysfs in /sys/devices/platform/80860F0A:00/tty/ttyS1/device/BCM2E55:00$ ), могут оставаться очень простыми, например это:

$ cat /etc/systemd/system/btattach-broadcom-ttyS1.service [Unit] Description=Start btattach, needed to enable Bluetooth for some UART-based Bluetooth Broadcom chipsets [Service] Type=simple # A delay is needed, 1s seems enough ExecStartPre=/bin/sleep 1s ExecStart=/usr/bin/btattach --bredr /dev/ttyS1 -P bcm

Эта systemd service будет работать как есть для других наборов микросхем Broadcom (отсюда параметр -P bcm ), появляющийся как дочерний элемент ttys1 (следовательно, /dev/ttyS1 ); только правило udev должно быть завершено, чтобы включить идентификаторы ACPI других вариантов набора микросхем.

Для наборов микросхем Broadcom, подключенных к другому узлу ttyS *, для этого случая может быть создана другая аналогичная systemd service (или, возможно, правильные параметры могут быть переданы из правила udev в службу systemd).

Перезагрузка планшета показывает, что команда btattach правильно выполняется при загрузке:

$ ps auxw | grep btattach root 2059 0.0 0.0 6372 720 ? Ss 23:17 0:00 /usr/bin/btattach --bredr /dev/ttyS1 -P bcm

и Bluetooth действительно включен и работает! Настройки Gnome Bluetooth перечисляют подключенные и отсканированные устройства и запускают $ bluetoothctl из командной строки, правильно отображая контроллер.

Удивительно, но при удалении начальной команды ожидания 1с, используемой для простое выполнение реальной команды, Bluetooth не работает вообще и не включен должным образом, несмотря на то, что btattach все еще работает правильно в списке фоновых процессов.

Не уверен, чтобы понять, что происходит совсем точно: на карту поставлена ​​проблема срочности и, конечно же, необходимая зависимость для ожидания, прежде чем предполагается запустить btattach …