本指南介绍如何使用 Clover 和 OpenCore 修复 macOS Monterey 及更高版本上的蓝牙问题。按照本指南操作,您将能够使用 Clover 或 OpenCore 引导加载程序在 macOS Monterey 及更高版本上启用蓝牙。
背景
最近,我们将一个版本升级到了 macOS Monterey 12.6,之前版本是随 macOS Big Sur 11.6.5 一起部署的。有趣的是,升级到 macOS Monterey 后,我们发现蓝牙在“系统偏好设置”中可用,但却无法正常工作。这意味着蓝牙没有开启/关闭功能,蓝牙地址为 NULL,状态为“关闭”。这仅仅意味着蓝牙连接不正确或系统无法通信。我们在这个版本上使用的是 Fenvi 的 Broadcom BCM94360NG。作为诊断的一部分,我们用一张新的网卡替换了原来的网卡,但没有任何变化。幸运的是,我们有完全相同的版本,但搭载的是 macOS Big Sur,所以我们交换了网卡,但仍然不行。由此,我们得出结论,网卡没有问题,问题可能是 M.2 WiFi 插槽或 BIOS。我们进一步检查,发现 M.2 WiFi 插槽和 BIOS 都完好无损。然而,我们注意到一个不寻常的情况:在 Windows 下,WiFi 可用,但没有蓝牙。考虑到卡固件已损坏,我们尝试更新固件,但发现固件正在加载并正常运行。现在,是时候调查 macOS 下的操作系统部分了。
在互联网上进行了一些快速研究后,我们了解到许多用户都遇到了类似的问题,主要是 Broadcom 的问题,蓝牙无法工作,但 WiFi 可以工作。在进行深入调查后,我们发现 Big Sur 的蓝牙实现与 Monterey 及更高版本不同,因此在较新的 macOS 版本上,它无法找到芯片组的固件,因此蓝牙固件在启动时不会加载,因此无法工作。自 macOS Monterey 以来,Apple 在各种外设(包括蓝牙)的实现方面进行了很大的改动。Apple 将蓝牙堆栈的部分内容从内核空间移到了用户空间,因此存在这个问题。这个问题存在于原生支持的卡(Broadcom,包括 AirPort 卡)以及社区支持的卡(例如 Intel)。但是,少数 Broadcom 卡(例如 Fenvi T919)是个例外,无论 macOS 版本如何,蓝牙都可以正常工作。我们使用了几个具有不同规格的不同版本。经过调查,我们注意到三种情况,如下所述。
情况 1
在这种情况下,蓝牙没有其地址(NULL)并且状态为关闭。
情况 2
在这种情况下,蓝牙确实有地址并且状态为开启,但无法初始化固件。WiFi 运行正常,并且 USB 映射已实现。在这种情况下,固件也无法加载。但是,在检查日志时,我们发现它bluetoothd
不断崩溃。您可以在下面找到详细信息。
案例 #3
在某些系统上,即使使用了所有修复方法,蓝牙地址仍可能显示为 NULL。除非存在有效的蓝牙地址,否则蓝牙将保持关闭状态,
检查启动日志后
解决方案
为防止 macOS Monterey 及更高版本出现蓝牙问题,有以下几种解决方案。根据情况,您可能需要使用下面列出的一种解决方案或几种解决方案的组合。
一、实现 USB 映射
自 macOS Big Sur (11.3.x) 以来,Apple 对其 USB 实现进行了一些更改。随着新重写的驱动程序,XhciPortLimit 被破坏。虽然始终建议映射 USB 端口,但现在已成为强制性要求。
此外,您需要更改蓝牙 USB 端口的连接器类型。由于 macOS 始终将蓝牙视为Internal
,因此最好将连接器类型更改为255
(内部)。有关更多信息,请参阅USB 端口映射。
二、删除重复的蓝牙
有些设置中主板通常附带板载 Intel WiFi/BT 卡,为了避免麻烦,许多用户倾向于安装 PCIe WiFi/BT 卡,这是错误的方法。这仅适用于 BIOS 有禁用板载 WiFi/BT 选项的情况。对于其余没有此选项的情况,您必须禁用不受支持的蓝牙模块以避免冲突。如果无法移除硬件(以避免损坏风险),您可以简单地排除 EHC/XHC 总线上的蓝牙端口。有关更多信息,请参阅USB 端口映射
。 但是,在某些情况下,蓝牙连接到内部集线器,禁用此类端口会导致整个集线器停止工作,从而导致连接到该端口的其他设备无法工作。因此,最好的方法是移除不受支持的蓝牙模块,并将其替换为兼容的模块。有关更多信息,请参阅蓝牙兼容性。
三. 绕过固件更新检查
在 Monterey 中,bluetoothd
它会识别并打开蓝牙IOUSBDevice
。然后,它会向另一个用于更新固件的守护进程发送 XPC 消息BlueTool
,以运行其内部脚本。在其内部脚本中,它BlueTool
会在必要时尝试更新固件。但是,在非原生芯片组上,BlueTool
无法找到芯片组的固件:
2021-06-10 19:33:57.527421+0100 0x35b Default 0x0 149 0 bluetoothd: [com.apple.bluetooth:Server.Core] Booting chipset
2021-06-10 19:33:57.527426+0100 0x35b Default 0x0 149 0 bluetoothd: [com.apple.bluetooth:Server.XPC] Creating XPCServiceConnection to com.apple.BlueTool
...
2021-06-10 19:33:57.527946+0100 0x35b Default 0x0 149 0 bluetoothd: [com.apple.bluetooth:Server.XPC] Opening connection to com.apple.BlueTool for UID 0
...
2021-06-10 19:33:57.544046+0100 0x6f1 Default 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] Running xpcRunBuiltinScript
...
2021-06-10 19:33:57.546883+0100 0x6f1 Error 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] getManufacturer could not find bootdata property
...
2021-06-10 19:33:57.553779+0100 0x6f1 Error 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] No WiFi - Iteration 0
...
2021-06-10 19:33:58.058809+0100 0x6f1 Error 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] Error - no firmware for this platform. Looking for <private> (null) DEV
2021-06-10 19:33:58.058817+0100 0x6f1 Default 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] <private> script attempt 1 of 1: result 10 execution time:513(MS)
2021-06-10 19:33:58.558993+0100 0x6f1 Default 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] builtin script completed with result 10
2021-06-10 19:33:58.559031+0100 0x6f1 Default 0x0 350 0 BlueTool: [com.apple.bluetooth:BlueTool] Completed handling of dictionary-xpc event
2021-06-10 19:33:58.559136+0100 0x35b Error 0x0 149 0 bluetoothd: [com.apple.bluetooth:Server.Core] Couldn't find a platform / chipset / firmware combination for the HW. Please file a bug with syslog, full ioreg output and result of `uname -a`.
2021-06-10 19:33:58.559137+0100 0x35b Error 0x0 149 0 bluetoothd: [com.apple.bluetooth:Server.Core] BlueTool failed to run boot script with result 10
...
2021-06-10 19:33:58.560254+0100 0x35b Default 0x0 149 0 bluetoothd: [com.apple.bluetooth:Server.Core] Notifying BT Firmware Crashed
BlueTool
然后返回10
XPC 回复的结果。此时,bluetoothd
由于非零值,因此终止。launchd
然后,将重新启动bluetoothd
,并继续循环。
要跳过固件更新检查,BlueTool
请检查是否存在/etc/bluetool/SkipBluetoothAutomaticFirmwareUpdate
。这可以手动创建,但我们将其替换为/System/Library/CoreServices/boot.efi
,因此无需手动创建,蓝牙可以在恢复模式下工作。由于boot.efi
应该始终存在,因此将始终跳过固件更新检查,并且由于检查的是文件的存在而不是内容,因此用此字符串替换原始字符串没有任何问题。
但是,为了使其正常工作,还必须正确设置传输(否则,文件将被忽略)。为了确定传输,BlueTool
(以及)在名为或 的注册表项中bluetoothd
查找属性。此属性的值决定了传输:用于 USB、用于 UART 和用于 PCIe。因此,我们将设置为(类型数据)并将自身重命名为。然后,将找到我们的注册表项,获取传输,检查跳过固件文件是否存在,跳过固件更新,然后完成并回复结果。然后将继续,蓝牙应该可以工作。BlueToolFixup 强制跳过尝试固件更新,以允许某些 Broadcom¹ 芯片组² 在 Monterey 上工作。它还正确设置了传输。¹BlueToolFixup 目前仅修补了 BlueTool 的固件更新检查。英特尔蓝牙似乎需要做更多的工作。² 目前尚未测试太多,并且并未测试所有功能(连续性)。这显然不是从 Mac 中拔出的卡所必需的,也不是完全原生且不需要 BrcmPatchRAM 的卡(即 BCM94360NG)。
四、绕过地址检查 自 macOS 12.4 和更新版本以来,在中引入了一项新的地址检查,如果两个蓝牙设备具有相同的地址,则会触发错误。但是,可以通过添加启动参数来绕过此检查。如果您没有多个蓝牙设备但有地址问题,这仍然很有用。有关更多信息,请参阅添加启动参数。
五、更新蓝牙固件 在某些系统上,即使使用了上述所有解决方案,蓝牙地址仍然可能显示为 NULL。除非存在有效的蓝牙固件,否则蓝牙将保持关闭状态。您必须为您的蓝牙设备烧录正确的固件。有关更多信息,请参阅烧录 Broadcom 蓝牙固件。transport-encoding
bluetooth
marconi-bt
0
3
7
transport-encoding
00000000
bluetooth
BlueTool
0
bluetoothd
bluetoothd
BlueTool
bluetoothd
-btlfxallowanyaddr
NULL
测试结果
以下是各种蓝牙BCM94360NG 的测试结果
结论
因此,我们可以得出结论,即使正确映射了 USB 端口,大多数 Broadcom 和 Intel WiFi/蓝牙卡在 Monterey 系统下也可能无法工作。原生支持的 AirPort 卡(例如 Broadcom BCM94360NG 和 BCM943602CS)也需要此解决方案。其他 Broadcom 型号可能也适用。我们可以确认,上述解决方案完全解决了 macOS Monterey 及更高版本上的蓝牙问题。
评论0