October 7

Bluetooth на хакинтоше: что купить и как подключить

Сборка такая: Gigabyte Z690 UD DDR4 с i5-13600KF, видеокарта RX 5700 XT, macOS 13.4.1, OpenCore 1.0.7, SMBIOS iMacPro1,1. На самой плате блютуза нет, как и в большинстве десктопных конфигураций. Значит, адаптер придётся покупать отдельно. И тут важно не ошибиться: разделяет «заработает сразу» и «не заведётся вообще» именно чип, а не цена и не возня с настройками.

Всё упирается в чип

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

Это видно по замеру:

ioreg -w0 | grep USBTransport

Все блютуз-транспорты в системе загружены, но каждый помечен !matched. Причина в их персоналиях:

CSRBluetoothHostControllerUSBTransport      | provider: IOResources
BroadcomBluetoothHostControllerUSBTransport | provider: IOResources
IOBluetoothHostControllerUSBTransport       | provider: IOResources

Если провайдер IOResources, а не IOUSBHostDevice, то с USB-устройствами такие транспорты не сопоставляются вообще, какие идентификаторы ни пропиши. Если перебрать все кексты в /System/Library/Extensions, под блютузом найдётся ровно две персоналии с USB-провайдером, и обе сидят в IOBluetoothFamily: «Bluetooth Entitlement» с idVendor: 1452 (это Apple) и конкретный хаб из Mac Pro 6,1.

Из этого следуют два вывода, и оба экономят вам вечер:

  • Гайды в духе «откройте IOBluetoothFamily.kext/…/Info.plist и впишите свои VID и PID», которые до сих пор вылезают первыми в поиске, мертвы по двум причинам. Устройство теперь отбирает демон, а системный том начиная с Big Sur запечатан, так что править там нечего. Именно для этого и сделан BlueToolFixup: он работает с памятью, а не с файлами.
  • Неподходящий чип настроить нельзя. Он либо есть в списке демона, либо его там нет. Промежуточного варианта не бывает, и карта портов его не создаст.

Четыре варианта, которые работают

Рабочих вариантов четыре. Сразу скажу про источники: своими руками я пока ни один не проверил, замена ещё едет. Поэтому у каждого варианта указано, откуда данные.

  • USB-донгл ASUS USB-BT400 и клоны. Чип Broadcom BCM20702A0. Ставить BlueToolFixup, BrcmPatchRAM3 и BrcmFirmwareData. Источник: Bluetooth 4.0, самый массовый рабочий вариант у хакинтошников.
  • USB-донгл Laird BT851 (04b4:f901). Чип Cypress CYW20704. Нужен BlueToolFixup, прошивка зашита в сам донгл. Источник: отчёт на tonymacx86 за август 2022, macOS 12.5. Трекпад, AirPods и Handoff работают, AirDrop у автора не поднялся.
  • Карта M.2 Intel AX200 или AX210 через переходник. Чип Intel. Нужны IntelBluetoothFirmware и IntelBTPatcher, а Wi-Fi закрывает AirportItlwm. Источник: проект OpenIntelWireless, сам не проверял.
  • Карта BCM94360CD на переходнике PCIe. Чип Broadcom. Ставить почти ничего не нужно, видится как родная. Источник: с ней работают Continuity и AirDrop, но стоит заметно дороже.

Как выбрать между ними:

Нужны только наушники, клавиатура и мышь. Берите донгл на BCM20702A0. Дешевле пути, который гарантированно даёт рабочий блютуз, нет, и половина сборок сидит именно на нём.

Нужны Handoff, AirDrop и разблокировка часами. Тогда только карта Broadcom с родными идентификаторами. Донгл этого не даст никогда: Continuity строится на связке Wi-Fi и блютуза с одной поддерживаемой карты, по отдельности блютуз задачу не решает. Это по руководству Dortania, личного замера у меня нет.

Wi-Fi в сборке тоже нет. AX210 закрывает обе задачи одной картой, но ценой Continuity. Мне как раз интереснее этот вариант: в EFI уже лежит отключённый AirportItlwm.

Чего брать не стоит: дешёвые донглы на CSR, 0a12:0001. macOS 13 отбраковывает их уже на этапе выбора устройства. Проверено на этой машине: демон находит донгл, читает идентификаторы и следующей строкой сообщает, что получить их не удалось.

[bm3_usb][GetProductAndVendorID] -- Found USB Device :
        idVendor = 0x0A12   idProduct = 0x0001   deviceClass = 0xE0
[bm3_usb][IOThreadFunc] -- USB -- Can't obtain vendorID and productID -- try again

Дальше идёт цикл, Transport layer initialization failed и десятки перезапусков демона подряд. Ни кексты, ни карта портов, ни снятие с устройства чужих процессов этот отказ не сдвигают, он повторяется слово в слово. Опознать такой донгл можно ещё по отзывам с фотографиями: у устройства, которое продают как Bluetooth 4.0, в свойствах стоит строка продукта BT2.0.

Без трёх вещей блютуз не заведётся

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

Кекст BlueToolFixup. Он нужен всем, кто сидит на macOS 12 и новее. Лежит в релизах BrcmPatchRAM, кладётся в EFI/OC/Kexts и прописывается в config.plist последней записью после Lilu, с MinKernel 21.0.0. Без него сторонние контроллеры молча игнорируются: ни ошибки, ни строки в журнале.

Прошивочные кексты под конкретный чип. Броадкомам, которым прошивку заливают при каждом старте, нужны BrcmPatchRAM3 и BrcmFirmwareData. Интелам нужны IntelBluetoothFirmware и IntelBTPatcher. Cypress и родным картам Broadcom больше ничего не требуется.

Порт с пометкой «внутренний». Контроллер блютуза macOS берёт только с того порта, где в карте портов стоит UsbConnector = 255. В моём UTBMap.kext это правится одним значением: у порта HS04, куда вставлен адаптер, 3 меняется на 255. Сработало сразу: у устройства появилось Built-In: Yes, а транспорт в профайлере сменился с UART на USB. Втыкать стоит в USB 2.0. Блютуз-адаптеры работают на Full Speed, скорость им не нужна, а перечисление на 2.0 идёт ровнее.

После правок прогоните ocvalidate по конфигу и перезагрузитесь.

Три команды покажут, почему молчит блютуз

На вопрос «почему не работает» почти всегда отвечают три команды. Вот что они выдают на моей машине прямо сейчас. Блютуз-железа в ней нет, и это видно по второму кадру.

Три команды: кекст, состояние контроллера, транспорты

kextstat: BlueToolFixup 2.7.2 и Lilu 1.7.2 загружены
system_profiler: Address NULL, State Off, чипсет BCM_4350C2 из SMBIOS
ioreg: четыре транспорта блютуза, все с пометкой !matched

Первая команда проверяет, жив ли кекст: kextstat | grep -iE "lilu|bluetool". Если BlueToolFixup в списке отсутствует, идти дальше некуда, проблема в конфиге, а не в железе.

Вторая показывает состояние контроллера: system_profiler SPBluetoothDataType. Смотрите на две строки. Если всё в порядке, там настоящий Address и State: On. Если нет, то Address: NULL и State: Off.

А вот строка, которая вводит в заблуждение многих: Chipset: BCM_4350C2. Она выводится даже тогда, когда блютуз-железа в машине нет вообще, как на кадре выше. Это чип настоящего iMac Pro, зашитый в bluetoothd, который смотрит на SMBIOS; ACPI-устройства за ней не стоит. Не радуйтесь этой строке и не подбирайте под неё кексты.

Третья показывает транспорты в ioreg. Пока у нужного стоит !matched, контроллер не подхвачен. Заметьте: транспортов там четыре, и загружены они всегда, так что само их присутствие ничего не гарантирует.

Подробности всегда лежат в журнале демона. В zsh log это встроенная команда, поэтому вызывать её нужно по полному пути:

/usr/bin/log show --last 5m --predicate 'process == "bluetoothd"' --style compact

Строка Found USB Device значит, что дело дошло до отбора. Transport layer initialization failed означает, что чип не подхватили.

У меня пока без результата

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

Если у вас на Ventura или Sonoma работает USB-донгл, расскажите в комментариях, какой именно. Интересуют чип и идентификаторы:

system_profiler SPUSBDataType | grep -A 6 -i bluetooth

Из ответов соберу список проверенного железа и вынесу его в конец статьи. Такого списка мне как раз и не хватало в начале.