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

Сборка: i5-13600KF, Gigabyte Z690 UD DDR4, 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.

Когда в provider стоит IOResources, а не IOUSBHostDevice, сопоставление с USB-устройствами не происходит вообще — вписывай туда любые идентификаторы. Если прочесать все kext в /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 загружены
kextstat: BlueToolFixup 2.7.2 и Lilu 1.7.2 загружены
system_profiler: Address NULL, State Off, чипсет BCM_4350C2 из SMBIOS
system_profiler: Address NULL, State Off, чипсет BCM_4350C2 из SMBIOS
ioreg: четыре транспорта блютуза, все с пометкой !matched
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

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