mihaits/rtl8852bd-bt-linux

GitHub: mihaits/rtl8852bd-bt-linux

一个通过重新打包 Realtek 专有固件并提供 DKMS 补丁模块的方式,让 RTL8852BD 蓝牙芯片在 Linux 上正常工作的驱动修复项目。

Stars: 0 | Forks: 0

# 适用于 Linux 的 RTL8852BD 蓝牙驱动 使 Realtek **RTL8852BD** 蓝牙模块(USB ID 为 `0bda:b853`)能够在 Linux 上正常工作。 这款芯片被广泛应用于 2024–2025 年笔记本电脑中常见的 RTL8852BE Wi-Fi/蓝牙 combo 卡中。 开箱即用的是 Wi-Fi 功能;而蓝牙功能在任何当前版本的 kernel 上均无法直接使用。 ## 这适用于我的机器吗? 需要进行两项检查 —— **两者**必须同时满足: ``` lsusb | grep -i 0bda:b853 # the Bluetooth USB adapter dmesg | grep -i "RTL: rom_version" # must say version=3 ``` `0bda:b853` 涵盖了整个 RTL8852BE 家族,但此修复专门针对报告为 **`rom_version=3`**(即“8852BD”)的特定芯片版本。如果您设备报告的版本号不同,说明它是不同的芯片版本,此修复并不适用您的情况。 `0bda:b853` / RTL8852BE combo 常见于 2024–2025 年的笔记本电脑中。已知出货包含该模块的产品系列有:**Lenovo** LOQ / IdeaPad / Legion / ThinkBook,**HP** Victus / 15-fc,**Acer** Nitro / Aspire,以及 **Asus** TUF / Vivobook。这并非兼容性保证 —— 同一型号在不同批次中可能会搭载 Intel 或 MediaTek 的模块,且并非所有的 8852BE 都是 `rom_version=3` 版本。上述的两条命令是唯一可靠的检测方法。 ## 问题所在 `btrtl` 能够检测到该芯片,但随后静默失败: ``` Bluetooth: hci0: RTL: examining hci_ver=0b hci_rev=000b lmp_ver=0b lmp_subver=8852 Bluetooth: hci0: RTL: rom_version status=0 version=3 Bluetooth: hci0: RTL: loading rtl_bt/rtl8852bu_fw.bin Bluetooth: hci0: RTL: didn't find patch for chip id 3 <-- the giveaway ``` 并且 `hci0` 始终无法开启: ``` $ hciconfig hci0 up Can't init device hci0: Invalid argument (22) $ hciconfig -a hci0: BD Address: 00:00:00:00:00:00 ``` 此版本的芯片报告 `rom_version=3`,因此需要带有 **eco 4** 的 firmware 补丁。`linux-firmware` 中的 `rtl8852bu_fw.bin` 仅包含 eco 1 和 2,因此解析器提取到零字节并返回 `-ENODATA``。这是一个 firmware 内容缺失的问题,而不是 kernel 的 bug —— 目前没有任何主线 kernel 或 `linux-firmware` 版本为这一芯片版本提供 eco-4 支持。 实际上,eco-4 firmware 是存在的,就在 Realtek 的 Windows 驱动程序中。本仓库对其进行了重新打包,并添加了该芯片所需的下载路径。 ## 环境要求 - `dkms`、`build-essential`、`linux-headers-$(uname -r)`、`python3` - `innoextract` —— 仅当您需要让安装程序处理厂商提供的 `.exe` 文件时需要 在基于 apt 的系统上,`install.sh` 会自动安装缺失的软件包。 ### Kernel 兼容性 本项目提供了一个**经过补丁修改的 `btrtl` 模块完整副本**,并通过 DKMS 针对您正在运行的 kernel 进行编译,以替换系统内置的 `btrtl`。在将其安装在未经测试的 kernel 上之前,有些影响值得您了解: - **新代码**(即 eco-4 下载功能)仅使用长期稳定的 kernel API(`request_firmware`、`kmalloc`、`__hci_cmd_sync`、`put_unaligned_le32`)—— 不包含任何容易因版本变动而出问题的部分。 - **基础** 的 `btrtl.c` 是 **kernel 6.8** 版本中该模块的快照。由于它会替换内置模块,其导出的符号必须与您 kernel 中已有的 `btusb` 保持 ABI 兼容。如果某个 kernel 更改了内部的 `btrtl`↔`btusb` 接口,此副本可能会编译失败,或者虽然编译成功但拒绝绑定(符号版本/CRC 不匹配)—— 在这种情况下,蓝牙将无法启动,您应该执行 `./uninstall.sh`。 - 任何树外的 DKMS 模块都不会经过签名,因此在 **Secure Boot** 下将无法加载,除非您注册了 MOK。请禁用 Secure Boot 或自行对模块进行签名。 **已测试环境:** Lenovo LOQ 15ARP10E,Ubuntu 22.04.5 HWE,kernel **6.8.0** (x86_64);该模块在 6.8 系列的其他小版本中也能顺利编译。其他 kernel 系列**未经测试** —— 6.8 LTS 系列(Ubuntu 22.04.5 / 24.04)是已知兼容的目标环境。在其他环境中尝试也是安全的:编译或绑定失败可以通过 `./uninstall.sh` 撤销,并恢复原生的 `btrtl`。 ## 第 1 步 — 获取 firmware **此处不包含任何 firmware。** 它是 Realtek 的专有代码,无法重新分发。您需要以下这一个文件: ``` rtl8852bd_mp_chip_new.dat ``` 这个 `.dat` 文件是适用于 **8852BD** 芯片的 Realtek firmware,与笔记本电脑型号无关 —— 任何厂商为 `0bda:b853` 适配器提供的 Realtek 蓝牙驱动包中都包含一份可用副本(Dell、HP、Asus 或 Realtek 官方驱动均有提供)。 前往您的设备厂商支持网站,下载您对应型号的**蓝牙驱动程序** —— 以 Lenovo 为例:*Support → 您的型号 → Drivers & Software → Bluetooth*。您下载到的是一个 **Windows 安装程序 `.exe`**,通常名称晦涩,例如 `53lo030fqufmvnj0.exe`。**请勿运行或重命名该文件** —— 只需记住其下载路径(例如 `~/Downloads/53lo030fqufmvnj0.exe`)。 您**不需要**手动提取任何内容:`install.sh` 会直接读取该 `.exe`(它会在后台替您运行 `innoextract`)。请直接跳到第 2 步。
可选:自行提取 .dat 文件,而不是直接传递 .exe 该 `.exe` 是一个 Inno Setup 安装程序,因此可以直接在 Linux 上进行解包 —— 无需 Windows 环境: ``` innoextract -s -d extracted ~/Downloads/53lo030fqufmvnj0.exe find extracted -name 'rtl8852bd_mp_chip_new.dat' ``` 完整性检查 —— 该文件的开头应为 ASCII magic `BTNIC003`: ``` head -c 8 path/to/rtl8852bd_mp_chip_new.dat # -> BTNIC003 ``` 然后,您可以将该 `.dat` 文件(而不是 `.exe`)传递给 `install.sh`。
## 第 2 步 — 安装 ``` git clone https://github.com/mihaits/rtl8852bd-bt-linux cd rtl8852bd-bt-linux ``` `install.sh` 接受**一个参数** —— 即您下载的驱动程序的路径。 将其指向厂商的 `.exe` 文件,它会自动提取 firmware: ``` sudo ./install.sh ~/Downloads/53lo030fqufmvnj0.exe ``` (请替换为您实际下载的文件名)。它会根据扩展名决定后续操作:`.exe` 会通过 `innoextract` 自动解包,其他所有格式都会被视为已提取的 `.dat` 文件: ``` sudo ./install.sh /path/to/rtl8852bd_mp_chip_new.dat ``` 无论采取哪种方式,安装程序随后都会编译 firmware,安装 DKMS 模块,清除可能存在的陈旧 rfkill 屏蔽,重新加载驱动程序,并验证结果。 ## 验证 ``` $ dmesg | grep -i rtl Bluetooth: hci0: RTL: RTL8852BD: using multi-record eco4 download Bluetooth: hci0: RTL: RTL8852BD eco4 firmware loaded (3 records) $ hciconfig hci0 hci0: Type: Primary Bus: USB BD Address: XX:XX:XX:XX:XX:XX UP RUNNING $ bluetoothctl scan on # should list nearby devices ``` 确认补丁是否真正在运行 —— 一旦补丁生效,控制器会报告不同的 firmware 版本: ``` sudo hcitool -i hci0 cmd 0x04 0x01 ``` | | HCI 版本 | fw 版本 | |---|---|---| | ROM(异常) | `0x0B` (BT 5.2) | `0x000B8852` | | 已打补丁(正常) | `0x0D` (BT 5.4) | `0x3C91950E` | ## 故障排除 **重启后蓝牙关闭 / `hci0` 显示为 `DOWN`,但 `dmesg` 看起来很干净。** 这几乎总是由于陈旧的 rfkill 屏蔽导致的,而不是 firmware 问题: ``` rfkill list bluetooth sudo rfkill unblock bluetooth ``` `systemd-rfkill` 会在每次启动时恢复*已保存的*屏蔽状态,因此如果该模块在损坏期间被禁用,该屏蔽状态在修复后依然会保留。`install.sh` 会清除已保存的状态;如果屏蔽再次出现,请在您的桌面设置中启用一次蓝牙,以便在关机时保存正确的状态。 **`hciconfig` 没有任何显示。** 请检查设备是否存在并已绑定: `lsusb | grep 0bda:b853` 和 `dmesg | grep -i bluetooth`。 **模块未能编译。** 请确保 `linux-headers-$(uname -r)` 与您当前运行的 kernel 相匹配,然后运行 `sudo dkms build -m rtl8852bd-bt -v 1.0` 查看错误。 **安装后依然使用的是 ROM firmware**(即上述的 `0x000B8852`)。说明下载过程已执行,但补丁未能启动 —— 请检查 `dmesg` 中是否有 `eco4` 相关错误,并确认您的 `.dat` 文件确实适用于 **8852BD**,而不是 `rtl8852b_mp_chip_new.dat` 或 `rtl8852c_mp_chip_new.dat`。 ## Kernel 更新 DKMS 会在 kernel 升级时自动重新编译该模块。您无需进行任何操作。 ## 卸载 ``` sudo ./uninstall.sh ``` ## 工作原理 `btrtl` 通常会解析 EPATCH/`RTBTCore` 格式的 firmware,并选择 eco 匹配 `rom_version + 1` 的代码片段。但在 `linux-firmware` 中的任何地方都找不到适用于此芯片的 eco-4 代码片段,因此该执行路径走不通。 Realtek 的 Windows 驱动程序并未针对此部件使用 EPATCH。它将补丁作为三个独立的记录放在一个 `BTNIC003` 容器中,每个记录都有各自的 RAM 加载地址,并通过厂商专有的下载协议进行推送: | opcode | 含义 | |---|---| | `0xfc61` | read memory — `[0x21][addr:le32]` | | `0xfc62` | **write memory** — `[0x21][dst:le32][value:le32]` | | `0xfc20` | download fragment — `[index][data…]`, ≤252 B, index 1…0x7f wrapping | 关键细节在于:`0x801200cc` 保存了控制器将 `0xfc20` 数据片段写入的流地址。在发送每个记录的数据片段之前,必须将其加载地址**写入该指针**: ``` for each record: fc62 [0x21][0x801200cc][record_load_addr] # aim the download buffer fc20 [idx][data] ... # plain indices, no bit 7 fc20 [0x80] # commit, once, at the end ``` 如果遗漏了指针写入,所有的记录都会被写入默认缓冲区(`0x8010f720`)。此时所有的命令依然会返回成功,firmware 也驻留在设备中,控制器也能响应 HCI —— 但是代码并没有存在于入口点所期望的位置,因此补丁永远无法启动,蓝牙模块依然无法工作。这种失败是完全静默的,这也正是该芯片在调试时如此令人困惑的原因。 `extract-firmware.py` 会将 `.dat` 记录重新打包为一个小巧的容器(包含 `E4RD` + 数量 + 每个记录的 `[load][len][blob]`),位于 `src/btrtl.c` 中打过补丁的 `rtl_download_eco4()` 函数会读取该容器。 如果您打算自行适配此方案,需要注意一个细节:根据您的 kernel 附带的容器格式不同,原生解析器在失败时会返回*不同*的 errno —— v1 `Realtech` EPATCH 格式返回 `-EINVAL`,v2 `RTBTCore` 格式则返回 `-ENODATA`。该 hook 对两者均予以接受,并按芯片 ID 限定范围,因此不会误吞不相关的错误。 ## 推送至上游 这是对 `btrtl.c` 的独立扩展,如果合入主线会更好。目前的阻碍在于 firmware 本身尚未包含在 `linux-firmware` 中;Realtek 需要发布适用于 8852BD 的 eco-4 文件。欢迎提交补丁和报告。 ## 许可协议 `src/btrtl.c`、`src/btrtl.h`、`src/hci_codec.h` 源自 Linux kernel,并保持 **GPL-2.0** 协议。本仓库中的脚本同样遵循 GPL-2.0 协议。 此处不包含或重新分发任何 Realtek 的 firmware。 ## 免责声明 **这是一个完全“vibecoded”(依靠 AI 凭感觉编写)的项目。** 它的调研、逆向工程以及端到端的编写工作均由 AI 完成 —— Claude Opus 4.8 和部分 Fable 5 —— 仅由我通过提示词并在属于我自己的这台机器上进行测试来驱动。**我不是驱动开发者,也不是 kernel 维护者**,我无法像那些专职编写蓝牙驱动的人那样对这段代码提供担保。本代码按“原样”提供,不附带任何形式的保证。 具体而言,这意味着:它会将厂商提供的 firmware 加载到您的蓝牙控制器上,并通过 DKMS 替换内置的 kernel 模块;目前仅在确切的一台笔记本电脑和一个 kernel 系列上得到了验证;尽管不良后果是可逆的(`./uninstall.sh` 可恢复原生模块),但您需自行承担运行风险。在以 root 身份运行这些脚本之前,请务必先阅读它们 —— 对于从互联网上获取的任何内容您都应如此谨慎,在这里更需加倍小心。 本项目为非官方性质,与 Realtek 或任何笔记本电脑厂商没有任何关系。
标签:Cutter, DKMS, Realtek, 内核模块, 固件, 安全资源, 客户端加密, 硬件驱动, 蓝牙