ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ubuntu 20.04蓝牙无法开启?MT7922驱动与固件修复指南

Ubuntu 20.04蓝牙无法开启?MT7922驱动与固件修复指南 如果你的 Ubuntu 20.04 装在一台新笔记本上装完系统后发现蓝牙图标灰了、设置里开关怎么点都弹不回来先别急着怀疑硬件坏了。这大概率是 MT7922 这颗无线网卡的驱动和固件没有跟上系统版本的节奏。MT7922 在笔记本上经常以 RZ616 的名字出现是一颗支持 Wi-Fi 6 和蓝牙 5.2 的二合一方案联发科这几年在消费市场上的铺量非常大但 Linux 生态对它的完整支持是最近一两年才慢慢补齐的。Ubuntu 20.04 默认内核相对保守装完系统后蓝牙直接没法用是很常见的事。这篇记录就是针对“Ubuntu 20.04 蓝牙无法开启、MT7922 驱动有问题”的完整排查思路和稳妥解法适合被这个问题折腾过的用户、刚接触 Linux 的新手以及想搞清楚驱动加载链路的技术爱好者。我会按从简单到复杂的顺序写建议先看第 1 章的故障分类因为不同症状对应的解决路径完全不一样。1. 先判断你的蓝牙问题属于哪种1.1 三种典型症状我接手过的类似案例里“蓝牙打不开”其实能分出三种完全不同的表现排查方向差很多。第一种是系统设置里的蓝牙开关是灰的点不动任务栏也没有蓝牙图标。这种情况多半是内核层面根本没有把蓝牙芯片识别出来或者识别到了但初始化失败连一个可用的蓝牙适配器都没向用户态暴露。第二种是开关能点但打开后一直转圈过几秒自己又弹回关闭状态。这种比第一种好一点说明硬件已经被系统看到了驱动模块也可能加载了问题大概率出在固件没有正确下发到芯片或者 BlueZ 服务在初始化时超时了。第三种更隐蔽蓝牙开关是开的也能搜到手机、耳机但就是连不上或者连上几秒就断。这种往往已经不是 MT7922 驱动识别问题而是协议栈版本、电源管理策略或者设备兼容性在作怪处理思路完全不一样。如果你只是想要一个快速判断打开终端执行rfkill list如果有蓝牙条目且显示“软阻塞/硬阻塞”这是软件开关或硬件开关的事不是驱动缺失如果根本没有蓝牙条目说明内核没把设备认出来后面的章节才是你的重点。1.2 排障前你需要确认的环境这篇文章按 Ubuntu 20.04 桌面版来写具体版本号我用的是 20.04.5 之后的镜像。请注意Ubuntu 20.04 从发布到后续小版本更新默认内核会变化GA 栈一直停在 5.4而 HWE 栈会滚动到 5.15来自 22.04 的 LTS 内核。这两个内核栈对 MT7922 的支持程度不同后面会分别讲。另外你得有 root 权限排障过程中会用到sudo。全程不需要图形界面也能操作SSH 进去一样能搞但涉及重启的步骤最好人在电脑前免得开机卡在 grub 或内核参数问题上没法及时处理。2. 定位硬件确认是不是 MT7922 在从中作梗2.1 三条命令看清无线网卡真面目很多人的电脑买回来包装盒和系统信息里只写了“Wi-Fi 6 网卡”“蓝牙 5.2”根本没有具体芯片型号。这时候要先确认硬件身份别一上来就盲目装驱动。打开终端执行这三条命令lspci -nnk | grep -i -A3 network lsusb uname -r如果网卡是 MT7922输出里大概率能看到Network controller [0280]: MEDIATEK Corp. MT7922 [14c3:0616]lsusb那边则会出现蓝牙对应的 USB 设备典型输出是Bus 003 Device 002: ID 0e8d:0616 MediaTek Wireless_Device0e8d:0616这个 USB ID 就是 MT7922 蓝牙部分的标准标识。uname -r会告诉你当前内核版本如果是 5.4 或者 5.8 这种老版本那基本已经能确定问题根源了。2.2 为什么 MT7922 在 Ubuntu 20.04 上这么容易翻车MT7922 和更早的 MT7921 在驱动族里属于同一套代码Linux 内核里的 PCIe 驱动模块名是mt7921e蓝牙部分走的是btusbbluetooth协议栈。光看名字你可能觉得“驱动有了啊”但实际上有几个问题叠加在一起第一个问题是内核里的设备白名单。MT7922 的设备 ID 是14c3:06165.12 之后的内核才开始把 MT7921 相关设备拉进支持列表但对 MT7922 的支持真正稳定下来要到 5.18 前后。Ubuntu 20.04 GA 内核是 5.4HWE 内核即使升级到 5.15对 MT7922 的支持依然不完整很多用户实测在 5.15 下蓝牙固件加载会直接报错。第二个问题是固件缺失。网卡芯片内部有自己的小 CPU驱动负责和它通信但芯片执行代码需要一套单独的 firmware 文件。MT7922 的蓝牙固件在 Linux-firmware 仓库里是 2023 年前后才逐步加入的Ubuntu 20.04 自带的linux-firmware包停留在 2020 年的快照/lib/firmware/mediatek/目录下根本没有BT_RAM_CODE_MT7922相关文件。芯片没固件上电后就没法完成蓝牙协议栈初始化表现出来就是蓝牙根本开不起来。第三个问题是 BlueZ 版本。Ubuntu 20.04 的 BlueZ 是 5.53对蓝牙 5.2 的新特性支持很有限。即使驱动和固件都被你“喂饱”了连接新耳机、手柄时也容易踩 A2DP 或 LE Audio 的兼容坑。所以给 MT7922 装驱动的本质不是跑一个 installer 那么简单而是要同时处理内核对芯片的识别、固件文件是否到位、用户态 BlueZ 版本是否匹配这三个层面。这也是为什么网上很多教程只让你“升级内核”或“更新固件”单做一步仍然不生效的原因。3. 排查链路按照“服务—内核—固件”的顺序找断点3.1 第一层蓝牙服务与 rfkill 状态先看最外层的服务和开关状态。执行systemctl status bluetooth rfkill list sudo dmesg -T | grep -i -E bluetooth|btusb|mt792|firmware | tail -50正常情况下bluetooth.service应该是active (running)。如果它处于failed或被 mask 掉了先试试sudo systemctl enable --now bluetooth sudo systemctl unmask bluetooth然后看rfkill list。这里有几种情况如果蓝牙条目显示Soft blocked: yes用sudo rfkill unblock bluetooth处理。如果显示Hard blocked: yes软件层管不了要去查笔记本的物理开关、键盘上的飞行模式快捷键或者 BIOS 里的 Wireless 开关。如果rfkill list里根本没有蓝牙条目说明内核层还没把设备暴露出来别在服务层继续耗时间直接跳去下一节。顺带提一句有些笔记本快捷键需要额外驱动才能用比如部分型号的FnF2实际发的是一个 ACPI 事件系统没有对应驱动时按键事件根本不会被处理。这种硬件开关问题在别的发行版上也可能出现不算 Ubuntu 特有。3.2 第二层内核模块和 USB 设备识别情况确认蓝牙服务没问题后看内核模块有没有正常挂上lsmod | grep -E btusb|bluetooth|mt7921btusb是蓝牙 USB 桥接驱动mt7921e是管控 PCIe 网卡的驱动。如果btusb没有加载手动加载一次sudo modprobe btusb如果报错说明内核里根本没有这个模块或者模块被黑名单拦了。检查一下/etc/modprobe.d/下有没有可疑的blacklistgrep -r -i blacklist /etc/modprobe.d/再看看 USB 层有没有识别到蓝牙设备lsusb -t如果能看到0e8d:0616挂在某个 hub 下面但rfkill list没有蓝牙条目说明驱动和硬件已经接触但初始化卡在更底层。这时就要翻内核日志了。3.3 第三层dmesg 里的固件加载日志这是整个排查过程里信息量最大的一步。执行sudo dmesg -T | grep -i -E bluetooth|btusb|mt792|firmware | tail -100常见的关键错误有这么几类Bluetooth: hci0: Direct firmware load for mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin failed with error -2 Bluetooth: hci0: Failed to load firmware file mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin (-2) Bluetooth: hci0: HCIfw download failed Bluetooth: hci0: command 0xfc01 tx timeout出现error -2是固件文件不存在出现error -22或timeout多是参数不匹配。如果日志里干脆只有usb 3-1: Product: MediaTek Wireless_Device而没有后续蓝牙设备初始化记录那多半是驱动不够新芯片没被真正“拉起来”。现在你应该已经能判断断点在哪一层了。接下来直接上方案还是那句老话从风险最低的开始操作能不动内核就不要动内核。4. 从低风险到高风险四个解法的操作顺序4.1 排除非驱动因素BIOS 开关、飞行模式和 rfkill很多人折腾了半天驱动最后发现是 BIOS 里的无线开关关掉了或者笔记本的飞行模式快捷键被误触。这个步骤 30 秒就能做完但最常见。先检查 BIOS开机时按F2/Del/F10进入设置界面不同品牌按键不一样找到类似Wireless、Bluetooth、WLAN的选项确保都是Enabled。有些商务本还会有Wireless Radio Control一并确认。然后是软件层sudo rfkill list all如果有蓝牙条目且Soft blocked: yes执行sudo rfkill unblock bluetooth如果你之前用过飞行模式可能要把所有无线都 unblock 再重新 block让状态机恢复正常。这一步是零风险操作建议先做。4.2 升级 HWE 内核与系统固件包确认不是硬件开关问题后第一种正式的解决手段是升级到 Ubuntu 20.04 的 HWE 内核同时更新系统自带的固件包。这个操作完全在官方软件源体系内风险最低也是我在大多数机器上优先尝试的方案。sudo apt update sudo apt install --install-recommends linux-generic-hwe-20.04 linux-firmware sudo reboot--install-recommends是为了把配套的硬件支持包一起拉进来。重启后执行uname -r正常会看到5.15.x或更高。如果蓝牙还是开不起来看dmesg是否仍然报BT_RAM_CODE_MT7922的固件缺失。5.15 内核里已经有mt7921e驱动但 Ubuntu 20.04 的linux-firmware包在软件源里更新不如上游快所以下一步我会直接手动更新固件。提示升级 HWE 内核不会卸载原来的旧内核重启时如果出现兼容性问题可以在 grub 菜单的“Advanced options for Ubuntu”里选旧内核启动临时回滚很方便。4.3 手动拉取最新 linux-firmware 并重载驱动这一步解决的是“内核认识芯片但没有固件可用”的情况。Ubuntu 20.04 仓库里的linux-firmware包版本太老但上游仓库已经包含了 MT7922 的蓝牙和 Wi-Fi 固件。我们需要手动把最新的mediatek固件目录复制进系统。如果你有 git 环境git clone https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git网络环境不方便也可以直接在浏览器里下载 tar 压缩包解压。拿到源码目录后先备份现有固件再拷贝覆盖sudo cp -r /lib/firmware/mediatek /lib/firmware/mediatek.bak sudo cp -r linux-firmware/mediatek /lib/firmware/最好把 MT7922 相关的 Wi-Fi 固件也一起更新就是mediatek目录下带MT7962或MT7922字样的文件里面通常包括WIFI_MT7962_patch_mcu_1_2_hdr.bin这类文件。虽然这次的问题在蓝牙但同一颗芯片的 WiFi 固件如果版本太旧也会影响后续稳定性。复制完成后重载蓝牙驱动sudo modprobe -r btusb sudo modprobe btusb sudo systemctl restart bluetooth这时候再执行dmesg -T | grep -i bluetooth如果看到了类似Bluetooth: hci0: Firmware already loaded或Bluetooth: hci0: Device setup complete的日志就说明固件已经成功下发。到这一步市面上绝大多数 MT7922 蓝牙打不开的问题都能解决。注意不要直接把整个linux-firmware仓库的文件全部覆盖到/lib/firmware/某些驱动对新固件的依赖和旧内核存在兼容性问题只更新mediatek目录最稳妥。如果真的碰上新固件和旧内核不兼容把备份的mediatek.bak恢复回去就行。4.4 使用 mainline 内核解决老内核支持不全的问题如果更新固件后内核日志依然没有进展那就别在旧内核上耗了。MT7922 想在图省事的 20.04 上稳定工作最好换一个 5.18 以上的内核。这里说两个选择第一个选择是安装 mainline 内核。到kernel.ubuntu.com/~kernel-ppa/mainline/找一个 6.2.x 版本我当时用的是 6.2.9兼容性比较稳。下载这三个 deb 文件linux-headers-6.2.9-xxx_all.deb linux-headers-6.2.9-xxx-generic_xxx_amd64.deb linux-image-6.2.9-xxx-generic_xxx_amd64.deb然后安装sudo dpkg -i linux-*.deb第二个选择如果你的电脑配置不算太老可以直接考虑升级到 Ubuntu 22.04 或 23.04。22.04 的 HWE 内核从 5.19 一路滚到 6.x对 MT7922 的支持比 20.04 好得多系统的 BlueZ 版本也更新省去后面各种兼容性折腾。我在自己的笔记本上就是靠等 22.04 发布的 HWE 内核彻底解决了蓝牙问题。注意安装 mainline 内核有两个坑。第一NVIDIA 闭源驱动在切换内核后需要重新编译最保险的做法是完全卸载驱动并重新安装或者先用开源驱动过渡第二如果 BIOS 开启了 Secure Bootunsigned 的 mainline 内核会被拒绝启动必须在安装前进入 BIOS 把 Secure Boot 关闭否则开机直接卡在引导界面。5. 实战中容易踩的坑和应对记录5.1 蓝牙能扫到耳机却连不上这类问题很多不是驱动而是 BlueZ 版本太旧或者耳机的蓝牙协议兼容性差。20.04 原版 BlueZ 5.53 在连接新出的蓝牙 5.2/5.3 耳机时经常出现配对成功后立刻断开、或者能搜到但无法连接的情况。先试这几步systemctl restart bluetooth bluetoothctl scan on pair XX:XX:XX:XX:XX:XX trust XX:XX:XX:XX:XX:XX connect XX:XX:XX:XX:XX:XX如果连接仍失败把出问题的设备从/var/lib/bluetooth/对应目录删掉重新配对sudo systemctl stop bluetooth sudo rm -rf /var/lib/bluetooth/* sudo systemctl start bluetooth实在不行可以考虑通过 PPA 安装新版 BlueZ但要注意新版 BlueZ 依赖较高版本的 libc、dbus 等系统组件人为升级容易把桌面环境搞崩操作前一定先备份系统快照或至少保持能进终端的退路。我的经验是如果只是要稳定用蓝牙耳机优先考虑升级整个系统到 22.04不会为单独一个新的 BlueZ 去冒破坏桌面环境的风险。5.2 升级内核导致 WiFi 或 NVIDIA 驱动异常MT7922 是 Wi-Fi 蓝牙二合一芯片Wi-Fi 端由mt7921e驱动负责。升级内核后如果发现 WiFi 也不见了大概率是新内核在老机器上需要更多固件依赖。刚才复制最新 mediatek 固件目录的做法同样能救 Wi-Fi因为包里面包含了 MT7962 的 Wi-Fi 固件。NVIDIA 闭源驱动是另一个重灾区。你升级 HWE 内核后如果系统里原来装了 runfile 方式的 N 卡驱动大概率开机后桌面分辨率变得很奇怪nvidia-smi也报错。解决办法是sudo dkms autoinstall如果 DKMS 无法自动完成需要重新执行一次runfile安装脚本让它为当前内核重新编译模块。装 mainline 内核时这个坑尤其明显不少人就是因为没先卸载 NVIDIA 驱动结果升级完内核直接没有桌面环境只能在 tty 里盲敲命令回滚。5.3 Secure Boot 导致驱动模块被拒载Ubuntu 20.04 默认在很多新电脑上会开启 Secure Boot。如果你自己编译模块、装 mainline 内核甚至从第三方 PPA 安装内核模块Secure Boot 都可能把你挡在外面。症状是开机时提示“Security Violation”或者系统启动后dmesg里有模块加载失败但信息很模糊。处理方式就是在 BIOS 里把 Secure Boot 关闭。别小看这个问题我在帮人远程排查时遇到过一个人所有驱动、固件都正确但蓝牙就是不能用最后发现是 Secure Boot 把第三方编译的模块全部拦截了。关闭后重启蓝牙马上正常。5.4 每次开机蓝牙都“抽风”怎么办有些机器装上驱动后一切正常但每次开机都要手动重启bluetooth.service才能用。这种情况多是驱动加载时序问题比如蓝牙 USB 设备在被系统初始化时固件还没就绪驱动就放弃了。最简单粗暴的解决办法是写一个 systemd 小服务开机后自动重载一次btusb驱动。新建一个服务文件/etc/systemd/system/bt-fix.service[Unit] DescriptionReload bluetooth driver Afterbluetooth.service [Service] Typeoneshot ExecStart/sbin/modprobe -r btusb ExecStart/sbin/modprobe btusb [Install] WantedBymulti-user.target然后启用sudo systemctl enable bt-fix.service sudo systemctl start bt-fix.service设置后每次开机都会自动重置一次蓝牙驱动对时序类问题非常有效。缺点是开机后可能要等一两秒蓝牙图标才亮起来这本来就不是什么大事。如果把这段时间踩过的坑汇总一下大概是下面这个对应关系症状可能原因优先处理方式蓝牙开关灰无法点击内核不识别芯片或驱动未加载升级 HWE/mainline 内核检查lsmodrfkill 里蓝牙显示 Hard blockedBIOS 开关、硬件无线开关检查 BIOS 与笔记本快捷键dmesg 报 BT_RAM_CODE_MT7922 加载失败固件缺失或版本太旧手动更新linux-firmware/mediatek能搜到设备但连不上BlueZ 版本过旧或配对缓存损坏清空/var/lib/bluetooth/后重新配对升级内核后 WiFi/NVIDIA 异常驱动与内核版本不匹配dkms autoinstall更新固件目录每次开机都需要手动重启蓝牙驱动加载时序问题增加 systemd 开机重载服务6. 最后再说几句实际操作体会这个 MT7922 的坑本质上不是“哪个发行版好”的问题而是硬件太新、内核和固件跟不上节奏的问题。Ubuntu 20.04 作为 2020 年发布的系统拿它伺候 2022 年之后的笔记本硬件遇到驱动问题几乎是必然的。我的经验是新笔记本跑 Linux优先找发行版 release notes 里确认无线网卡兼容性如果已经踩坑了别一上来就编译内核按“硬件开关 → 系统包升级 → 固件更新 → 换内核”的顺序走每步都看日志确认效果基本不会把系统搞坏。我自己那台机器的最终状态是固件更新到最新、内核换到 6.2然后在 22.04 的 HWE 内核上稳定用了大半年再也没碰过蓝牙打不开的问题。顺手把之前想在 Ubuntu 上玩的蓝牙串口、蓝牙测距这些折腾也一起解禁了——驱动层不跑通应用层全是空中楼阁。如果你照着做完了还是不行别死磕外接一个 CSR 芯片的 USB 蓝牙适配器是成本最低的兜底方案但它只解决“能用”不解决“原装硬件为什么不行”的好奇心。祝你顺利把蓝牙点亮。
返回列表