在部分采用 Broadcom 蓝牙控制器的 Intel Mac 硬件上,Arch Linux 可能能够识别蓝牙硬件,却无法真正创建可用的 BlueZ 控制器。典型表现是系统已经加载蓝牙驱动、rfkill 也能看到 hci0,但 KDE 中没有蓝牙图标,bluetoothctl 无法列出控制器。

这类问题并不一定意味着 Linux 缺少驱动,也不一定需要额外安装固件。对于 BCM4350C0 这类通过 UART 连接的控制器,问题可能出在控制器自身保留的通信状态,尤其是 UART 波特率状态。

故障现象

系统已经安装并启用了 BlueZ:

pacman -Q bluez bluez-utils
systemctl status bluetooth

结果显示:

bluez 5.87-2
bluez-utils 5.87-2

bluetooth.service
Active: active (running)

说明用户空间的 Bluetooth 服务本身正常。

继续检查:

bluetoothctl list

没有任何输出。

使用:

sudo btmgmt info

则显示:

Index list with 0 items

这说明 BlueZ 服务虽然正常运行,但内核并没有成功向它提供一个可使用的 HCI Controller。

确认硬件是否存在

首先检查 rfkill

rfkill list

可以看到:

0: hci0: Bluetooth
        Soft blocked: no
        Hard blocked: no

这非常重要。

它说明:

  • 蓝牙设备确实已经被内核发现
  • 设备没有被软件禁用
  • 设备没有被硬件禁用

因此问题并不是简单的 Bluetooth 开关状态。

再检查内核模块:

lsmod | grep -E 'btusb|btbcm|hci_uart|bluetooth'

可以看到类似:

hci_uart
btbcm
bluetooth

其中最值得注意的是:

hci_uart
btbcm

这说明该 Broadcom 蓝牙控制器通过 UART 接入,而不是普通 USB 蓝牙设备。

因此:

lsusb | grep -i bluetooth

没有结果并不代表蓝牙硬件不存在。

从内核日志找到真正的故障点

最关键的诊断命令是:

sudo journalctl -b -k --no-pager |
    grep -iE 'bluetooth|hci0|hci_uart|bcm|firmware|baud|ttyS'

日志中出现:

dw-apb-uart.2: ttyS4 at MMIO ... base_baud = 3000000
serial serial0: tty port ttyS4 registered

Bluetooth: HCI UART driver ver 2.3
Bluetooth: HCI UART protocol Broadcom registered

hci_uart_bcm serial0-0: Unexpected ACPI gpio_int_idx: -1
hci_uart_bcm serial0-0: Unexpected number of ACPI GPIOs: 0
hci_uart_bcm serial0-0: No reset resource, using default baud rate

随后出现真正导致初始化失败的信息:

Bluetooth: hci0: command 0xfc18 tx timeout
Bluetooth: hci0: BCM: failed to write update baudrate (-110)
Bluetooth: hci0: Failed to set baudrate
Bluetooth: hci0: command 0xfc18 tx timeout
Bluetooth: hci0: BCM: Reset failed (-110)

至此基本可以确定问题。

Linux 已经正确识别:

  • UART 控制器
  • Broadcom HCI UART 协议
  • hci_uart_bcm
  • BCM 蓝牙设备

但是在尝试修改蓝牙控制器 UART 波特率时,控制器没有正常响应。

错误码:

-110

对应超时。

问题本质:UART 两端通信状态不一致

BCM4350C0 蓝牙控制器通过 UART 与系统通信。

初始化时,主机和蓝牙芯片必须先使用一致的波特率进行通信,然后才能进一步切换到更高速度。

日志中的:

No reset resource, using default baud rate

意味着 Linux 无法通过正常的 ACPI GPIO reset 机制完整复位这个控制器,于是只能假定控制器当前处于默认通信状态。

如果蓝牙芯片此前已经被另一个操作系统设置成了不同的 UART 状态,例如更高的波特率,而控制器又没有在普通重启过程中彻底恢复默认状态,就会产生一个典型问题:

Linux 主机:使用默认 baud rate 发送命令
Bluetooth 控制器:仍然工作在之前留下的 baud rate

双方波特率不一致,彼此自然无法理解数据。

结果就是:

command 0xfc18 tx timeout

随后波特率修改和控制器 Reset 都失败。

这也解释了一个看似矛盾的现象:

rfkill 能看到 hci0

但:

bluetoothctl list

却什么都没有。

底层 UART 设备存在,但 HCI Controller 没有成功完成初始化。

修复方法:彻底关机并重置 SMC

这种情况下没有立即安装额外驱动,也没有修改 BlueZ 配置,而是先彻底关闭系统:

sudo poweroff

随后执行 SMC Reset。

对于采用传统 Intel SMC 的相关 Mac 硬件,可以在完全关机之后,通过内置键盘执行对应的 SMC 重置组合键,然后再正常启动。

完成 SMC Reset 后直接进入 Arch Linux。

启动完成后,系统任务栏立即出现了蓝牙图标。

也就是说,蓝牙控制器已经重新被系统正常初始化。

再次检查:

bluetoothctl list

此时应该能够看到实际的 Controller。

也可以运行:

sudo btmgmt info

确认 BlueZ Management Interface 已经存在有效的 Bluetooth Index。

最终蓝牙功能恢复正常,可以正常搜索、配对并使用蓝牙耳机等设备。

为什么 SMC Reset 有效

SMC Reset 与重新安装驱动完全不同。

这次故障中:

  • Linux 蓝牙驱动已经存在
  • BlueZ 已经正常运行
  • Broadcom UART 驱动已经加载
  • 内核已经检测到 hci0

真正异常的是蓝牙控制器自身所处的硬件状态。

普通 warm reboot 并不一定能够让所有外围控制器完全断电并恢复出厂初始化状态。

SMC Reset 可以重新初始化相关底层硬件管理状态,从而使 BCM4350C0 回到 Linux 驱动能够正确通信的状态。

之后 Linux 即可重新完成:

UART 初始化
    ↓
Broadcom HCI 初始化
    ↓
baud rate 设置
    ↓
HCI Controller 注册
    ↓
BlueZ 获得 Controller
    ↓
KDE 显示 Bluetooth

SMC Reset 不等于 NVRAM Reset

需要特别区分两个概念:

SMC Reset

和:

NVRAM / PRAM Reset

它们不是同一件事情。

SMC 主要负责或参与:

  • 电源管理
  • 电池管理
  • 风扇
  • 部分外围设备状态
  • 睡眠与唤醒
  • 某些底层硬件初始化

NVRAM 则保存另一类固件级参数。

因此,执行 SMC Reset 本身并不等价于清空 NVRAM。

如果系统中曾经通过:

nvram

设置某些启动相关参数,正常的 SMC Reset 不应被视为一次 NVRAM Reset。

这也是处理此问题时一个比较安全的重要区别。

Wi-Fi 固件错误不要和 Bluetooth 混淆

同一份日志中还可能看到:

brcmfmac4350c2-pcie....bin failed with error -2
brcmfmac4350c2-pcie.txt failed with error -2
brcmfmac4350c2-pcie.clm_blob failed with error -2

这些信息来自:

brcmfmac

它属于 Broadcom Wi-Fi 驱动。

后面如果继续出现:

Firmware: BCM4350/5 ...

说明 Wi-Fi 已经找到了可使用的 fallback firmware 并继续初始化。

因此不要因为看到:

brcmfmac

和:

BCM4350

就把 Wi-Fi 固件日志与 Bluetooth 故障混为一谈。

虽然 Wi-Fi 和 Bluetooth 可能来自同一套 Broadcom 无线芯片方案,但 Linux 中是两套不同的驱动路径。

本次 Bluetooth 故障真正需要关注的是:

hci_uart_bcm
Bluetooth: hci0
failed to write update baudrate
Reset failed

不需要为了蓝牙安装 broadcom-wl

另一个容易走错的方向是安装:

broadcom-wl

但这个软件包主要针对 Broadcom Wi-Fi。

当前故障已经明确发生在:

hci_uart_bcm

也就是 Bluetooth UART 初始化阶段。

因此没有理由为了这个问题修改已经正常工作的 Wi-Fi 驱动。

在 Linux 硬件排障中,区分:

Wi-Fi
Bluetooth

虽然两者可能共享同一块无线硬件,但驱动链路完全可能不同。

hciconfig 不存在也不是问题

部分旧教程会要求运行:

hciconfig

现代 BlueZ 环境中,这个旧工具可能默认并不存在。

例如:

bash: hciconfig: command not found

本身并不是故障。

现在更有价值的工具包括:

bluetoothctl

以及:

btmgmt

尤其是:

sudo btmgmt info

如果返回:

Index list with 0 items

已经足够说明 BlueZ 当前没有获得任何初始化完成的 Bluetooth Controller。

推荐的诊断流程

遇到类似“Linux 能看到蓝牙硬件,但桌面环境没有 Bluetooth”的情况,可以按下面顺序排查。

首先确认 BlueZ:

pacman -Q bluez bluez-utils
systemctl status bluetooth

再确认 rfkill:

rfkill list

确认模块:

lsmod | grep -E 'btusb|btbcm|hci_uart|bluetooth'

检查 BlueZ 是否真正拿到了 Controller:

bluetoothctl list
sudo btmgmt info

最后读取内核日志:

sudo journalctl -b -k --no-pager |
    grep -iE 'bluetooth|hci0|hci_uart|bcm|firmware|baud|ttyS'

如果看到类似:

hci_uart_bcm
No reset resource, using default baud rate
command 0xfc18 tx timeout
failed to write update baudrate
Failed to set baudrate
Reset failed

那么重点就不应该继续放在:

BlueZ 配置
KDE 设置
rfkill
额外软件包

而应该考虑 Broadcom UART 控制器是否处于没有被完全复位的硬件状态。

总结

这次故障表面上看像是 Arch Linux 不支持内置 Bluetooth:

BlueZ 正常
rfkill 有 hci0
KDE 没有 Bluetooth
bluetoothctl 没有 Controller

但日志最终证明 Linux 的驱动支持实际上已经存在。

真正的故障点是:

BCM4350C0
    ↓
Broadcom HCI UART
    ↓
控制器未正确恢复默认 UART 状态
    ↓
Linux 使用默认 baud rate 初始化
    ↓
0xfc18 命令超时
    ↓
baud rate 设置失败
    ↓
HCI Controller 注册失败

通过彻底关机并执行 SMC Reset,使蓝牙控制器恢复到正常的底层初始化状态后,Arch Linux 即可正常识别并使用 Bluetooth。

这类故障很适合说明一个 Linux 硬件排障原则:

“设备被内核发现”与“设备完成初始化并可被用户空间使用”是两个不同阶段。

rfkill 中出现 hci0,只能证明底层硬件路径已经存在;真正判断 Bluetooth 是否可用,还应该继续检查:

bluetoothctl list

和:

btmgmt info

再结合 kernel log 判断 HCI 初始化是否完整完成。

Leave a Reply

Your email address will not be published. Required fields are marked *