LubanCat-3 (RK3576) 安装 Realtek RTL8851BU WiFi+蓝牙驱动全流程

本文记录在 LubanCat-3 开发板(RK3576,Ubuntu 22.04.5,内核 6.1.99-rk3576)上编译安装 Realtek RTL8851BU WiFi+蓝牙 combo 驱动的完整过程。提供一键安装脚本,也详解每个步骤的原理和踩坑经验。

适用环境:LubanCat-3 / RK3576 / Ubuntu 22.04 / Kernel 6.1.99-rk3576
目标芯片:Realtek RTL8851BU(WiFi 6 + BT 5.3 combo)
USB 设备 ID:0bda:1a2b(CDROM 模式)→ 0bda:b851(WiFi+BT 模式)

资源下载

本文所用驱动源码、固件及一键安装脚本已打包:

wifi_linux.zip(约 11.2 MB,含 WiFi/BT 源码 + lubancat3_rtk_fix.sh 一键脚本)

解压后目录结构:

1
2
3
4
5
wifi_linux/
├── lubancat3_rtk_fix.sh # 一键安装脚本
└── Linux/
├── WIFI/ # 8851bu WiFi 驱动源码
└── BT/ # rtk_btusb 蓝牙驱动源码 + 固件

1. 快速开始(一键安装)

如果你只想尽快跑起来,三步搞定:

1
2
3
4
5
6
7
8
9
# 1. 解压
unzip wifi_linux.zip
cd wifi_linux

# 2. 给脚本执行权限
chmod +x lubancat3_rtk_fix.sh

# 3. 一键执行(需要 sudo)
sudo ./lubancat3_rtk_fix.sh

脚本会自动完成以下全部流程:安装编译依赖 → 修复源码 bug → 编译 WiFi 驱动 → 安装 WiFi 驱动 → 复制蓝牙固件 → 编译蓝牙驱动 → 安装蓝牙驱动 → USB 模式切换 → 加载模块 → 验证结果。

整个过程约 12 分钟(主要耗时在编译)。执行完毕后如果 wlan0 没有立即出现,等几秒或 sudo reboot 重启即可。

下面详细介绍每个步骤的原理,方便遇到问题时排查。

2. 环境准备

2.1 确认系统信息

1
2
3
4
5
uname -a
# Linux lubancat 6.1.99-rk3576 #... SMP ... aarch64 aarch64 aarch64 GNU/Linux

cat /etc/os-release
# Ubuntu 22.04.5 LTS

2.2 安装编译工具链

1
2
sudo apt-get update
sudo apt-get install -y build-essential linux-headers-$(uname -r) git python3-usb

注意python3-usb(pyusb)后续用于 USB 模式切换,务必提前安装。

2.3 准备驱动源码

将下载的 wifi_linux.zip 传到开发板(通过 U 盘、scp 或其他方式),解压:

1
2
unzip wifi_linux.zip
cd wifi_linux/Linux

3. 编译 WiFi 驱动 (8851bu)

3.1 修复源码 bug

打开 WIFI/phl/phl_regulation_def.h,有一处 sizeof 写错了结构体类型,会导致编译报 sizeof-array-div 错误。

Bug 位置 — 第 114 行附近,PHL_GET_CHDEF_6G 宏:

1
2
3
4
5
// 错误写法
u8 size = sizeof(_chdef_tbl_) / sizeof(struct regulatory_domain_mapping_6g);

// 正确写法
u8 size = sizeof(_chdef_tbl_) / sizeof(struct chdef_6ghz);

一键脚本中已包含自动修复逻辑,会精确定位 PHL_GET_CHDEF_6G 宏并替换,不会影响第 122 行的 PHL_GET_DOMAIN_INDEX_6G 宏(那个是正确的)。

手动修复命令:

1
2
cd WIFI
sed -i '/PHL_GET_CHDEF_6G/,/;/ s/sizeof(struct regulatory_domain_mapping_6g)/sizeof(struct chdef_6ghz)/' phl/phl_regulation_def.h

3.2 编译驱动

关键:必须显式指定 ARCH=arm64,不能依赖 uname -m 的默认值(会返回 aarch64,但内核目录是 arch/arm64/)。

1
2
cd WIFI
sudo make all ARCH=arm64

编译时间约 10 分钟。如果通过 SSH 操作,建议用 nohup 放到后台避免超时:

1
2
nohup sudo make all ARCH=arm64 > /tmp/wifi_build.log 2>&1 &
tail -f /tmp/wifi_build.log

编译成功后生成 8851bu.ko(约 10.8MB)。

3.3 安装并加载 WiFi 模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo cp 8851bu.ko /lib/modules/$(uname -r)/kernel/drivers/net/wireless/
sudo depmod -a
sudo modprobe 8851bu

# 验证
lsmod | grep 8851bu
# 8851bu 6148096 0

dmesg | tail -5
# RTW: module init start
# RTW: rtl8851bu v1.19.10-...
# RTW: rtw_inetaddr_notifier_register
# usbcore: registered new interface driver rtl8851bu
# RTW: module init ret=0

此时 8851bu 模块已加载,但由于 USB 设备还在 CDROM 模式,wlan0 接口不会出现。需要先完成 USB 模式切换。

4. 编译安装蓝牙驱动 (rtk_btusb)

4.1 复制固件文件

1
2
3
4
sudo cp BT/rtkbt-firmware/lib/firmware/rtl8851bu_* /lib/firmware/
ls /lib/firmware/rtl8851bu*
# /lib/firmware/rtl8851bu_config
# /lib/firmware/rtl8851bu_fw

4.2 编译蓝牙驱动

1
2
cd BT/usb
sudo make all ARCH=arm64

4.3 安装并加载蓝牙模块

1
2
3
4
5
6
7
8
9
10
11
sudo cp rtk_btusb.ko /lib/modules/$(uname -r)/kernel/drivers/bluetooth/
sudo depmod -a
sudo modprobe rtk_btusb

# 验证
lsmod | grep rtk_btusb
# rtk_btusb 77824 0

dmesg | grep rtk_btusb
# rtk_btusb: Realtek Bluetooth USB driver ver 3.1...
# usbcore: registered new interface driver rtk_btusb

蓝牙模块加载完成,但同样需要 USB 模式切换后才能看到 hci0 设备。

5. USB 模式切换(核心难点)

这是整个流程中最关键的一步。RTL8851BU 的 USB 设备初始状态是 CDROM/Mass Storage 模式(用于 Windows 安装驱动),需要发送特定 SCSI 命令切换到 WiFi+BT 模式。

5.1 确认当前状态

1
2
lsusb
# Bus 001 Device 003: ID 0bda:1a2b Realtek Semiconductor Corp. RTL8188GU 802.11n WLAN Adapter (Driver CDROM Mode)

设备显示为 0bda:1a2b,Product 字符串为 “DISK”,bInterfaceClass 为 Mass Storage (8)。这就是 CDROM 模式。

5.2 尝试 usb_modeswitch(失败)

最常见的思路是用 usb_modeswitch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 方法 1:Windows 扩展描述符
sudo usb_modeswitch -W -v 0bda -p 1a2b
# 结果:Warning: no switching method given

# 方法 2:标准 SCSI eject
sudo usb_modeswitch -J -v 0bda -p 1a2b
# 结果:OK, message successfully sent — 但设备没有任何变化

# 方法 3:创建配置文件
sudo tee /usr/share/usb_modeswitch/0bda:1a2b << EOF
TargetVendor=0x0bda
TargetProduct=0x8851
StandardEject=1
EOF
sudo usb_modeswitch -v 0bda -p 1a2b
# 结果:仍然无效

结论usb_modeswitch 的所有标准方法对 0bda:1a2b 均无效。

5.3 成功方案:pyusb 直接发送 SCSI 命令

通过 Python pyusb 库直接向 USB 设备发送 Bulk-Only Transport (BOT) 协议的 SCSI 命令。

原理:USB Mass Storage 设备使用 BOT 协议通信,主机通过 Bulk OUT 端点发送 Command Block Wrapper (CBW, 31字节),设备通过 Bulk IN 端点返回 Command Status Wrapper (CSW, 13字节)。切换流程分两步:先发 ALLOW MEDIUM REMOVAL(0x1e)解除介质锁定,再发 START STOP UNIT(0x1b)带 Load/Eject 位触发模式切换。

一键脚本中已内嵌了完整的 Python 切换逻辑。如需手动执行,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/env python3
import usb.core
import struct
import time

dev = usb.core.find(idVendor=0x0bda, idProduct=0x1a2b)
if dev is None:
print("设备未处于 CDROM 模式")
exit(0)

# 解除内核驱动绑定
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)

# 获取端点
cfg = dev.get_active_configuration()
intf = cfg[(0, 0)]
ep_out = ep_in = None
for ep in intf:
if usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_OUT:
ep_out = ep
else:
ep_in = ep

def send_scsi(cmd, tag):
cbw = struct.pack('<IIIB', 0x43425355, tag, 0, 0)
cbw += struct.pack('<BB', 0, len(cmd))
cbw += cmd + b'\x00' * (31 - 6 - len(cmd))
dev.write(ep_out.bEndpointAddress, cbw, timeout=5000)
try:
dev.read(ep_in.bEndpointAddress, 13, timeout=3000)
except:
pass

# 步骤 1:ALLOW MEDIUM REMOVAL
send_scsi(bytes([0x1e, 0, 0, 0, 0, 0]), 1)
time.sleep(0.5)

# 步骤 2:START STOP UNIT (eject)
send_scsi(bytes([0x1b, 0, 0, 0, 0x02, 0]), 2)
time.sleep(2)

# 验证
if usb.core.find(idVendor=0x0bda, idProduct=0x1a2b) is None:
print("切换成功!")

运行:

1
sudo python3 usb_switch.py

预期输出

1
切换成功!

5.4 切换后的设备信息

1
2
3
4
5
6
7
lsusb
# Bus 001 Device 009: ID 0bda:b851 Realtek Semiconductor Corp. 802.11ax WLAN Adapter

lsusb -t
# |__ Port 1: Dev 9, If 2, Class=Vendor Specific Class, Driver=rtl8851bu, 480M
# |__ Port 1: Dev 9, If 0, Class=Wireless, Driver=rtk_btusb, 480M
# |__ Port 1: Dev 9, If 1, Class=Wireless, Driver=rtk_btusb, 480M

设备现在暴露了 3 个接口:If 0/1 是 Bluetooth(rtk_btusb 驱动),If 2 是 WiFi(rtl8851bu 驱动)。

6. 验证功能

6.1 WiFi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ip link show wlan0
# 7: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> ... state UP

iwconfig wlan0
# wlan0 IEEE 802.11AX ESSID:"CMCC-pu5E-5G"
# Mode:Managed Frequency:5.24 GHz Access Point: AC:56:7B:95:20:61
# Bit Rate:600 Mb/s Signal level=62/100

# 连接 WiFi(如未自动连接)
nmcli device wifi list
nmcli device wifi connect <SSID> password <密码>

# 测试网络
ping -c 3 8.8.8.8

6.2 蓝牙

1
2
3
4
5
6
7
8
9
10
11
hciconfig hci0
# hci0: Type: Primary Bus: USB
# BD Address: 6C:1F:F7:E6:32:98 ACL MTU: 1021:8 SCO MTU: 255:12
# UP RUNNING

rfkill list
# 0: hci0: Bluetooth Soft blocked: no Hard blocked: no
# 1: phy0: Wireless LAN Soft blocked: no Hard blocked: no

# 扫描蓝牙设备
sudo hcitool inq

补充:BLE 扫描 hcitool lescan 可能出现 “Input/output error”,这是 rtk_btusb 驱动版本对 LE 命令支持不完整导致的,不影响经典蓝牙功能。

7. 设置开机自动加载

7.1 模块自动加载

1
2
echo "8851bu" | sudo tee -a /etc/modules
echo "rtk_btusb" | sudo tee -a /etc/modules

7.2 USB 模式切换自动化

创建 systemd 服务,开机自动执行 USB 模式切换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
sudo tee /usr/local/bin/rtl8851bu_modeswitch.py << 'PYEOF'
#!/usr/bin/env python3
"""RTL8851BU USB mode switch: CDROM (0bda:1a2b) -> WiFi+BT (0bda:b851)"""
import usb.core, struct, time, sys

def switch_mode():
dev = usb.core.find(idVendor=0x0bda, idProduct=0x1a2b)
if dev is None:
return True
try:
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
except:
pass
cfg = dev.get_active_configuration()
intf = cfg[(0, 0)]
ep_out = ep_in = None
for ep in intf:
if usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_OUT:
ep_out = ep
else:
ep_in = ep
if not ep_out or not ep_in:
return False
def send_scsi(cmd, tag):
cbw = struct.pack('<IIIB', 0x43425355, tag, 0, 0)
cbw += struct.pack('<BB', 0, len(cmd))
cbw += cmd + b'\x00' * (31 - 6 - len(cmd))
dev.write(ep_out.bEndpointAddress, cbw, timeout=5000)
try:
dev.read(ep_in.bEndpointAddress, 13, timeout=3000)
except:
pass
send_scsi(bytes([0x1e, 0, 0, 0, 0, 0]), 1)
time.sleep(0.5)
send_scsi(bytes([0x1b, 0, 0, 0, 0x02, 0]), 2)
time.sleep(2)
return usb.core.find(idVendor=0x0bda, idProduct=0x1a2b) is None

if __name__ == '__main__':
sys.exit(0 if switch_mode() else 1)
PYEOF

sudo chmod +x /usr/local/bin/rtl8851bu_modeswitch.py

sudo tee /etc/systemd/system/rtl8851bu-modeswitch.service << 'EOF'
[Unit]
Description=RTL8851BU USB Mode Switch
After=usb.target
Before=NetworkManager.service

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /usr/local/bin/rtl8851bu_modeswitch.py
RemainAfterExit=yes
TimeoutStartSec=15

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable rtl8851bu-modeswitch.service

8. 踩坑总结

问题 原因 解决方案
WiFi 驱动编译报 sizeof-array-div 错误 phl_regulation_def.h 第 114 行 sizeof 使用了错误的结构体类型 sizeof(struct regulatory_domain_mapping_6g) 改为 sizeof(struct chdef_6ghz)
编译报 arch/aarch64/Makefile: No such file Makefile 默认用 uname -m 得到 aarch64,但内核目录是 arch/arm64/ 编译时显式指定 ARCH=arm64
SSH 编译超时 编译时间超过 SSH 会话超时 使用 nohup + 后台脚本 + 日志轮询
USB 设备始终显示为 CDROM 模式 usb_modeswitch 标准方法对 0bda:1a2b 无效 用 pyusb 发送 SCSI BOT 命令(ALLOW MEDIUM REMOVAL + START STOP UNIT)
蓝牙 hciconfig 无设备 USB 设备未切换模式,BT 接口不可见 先完成 USB 模式切换
蓝牙 rfkill soft blocked 某些操作触发了 rfkill 开关 sudo rfkill unblock all
BLE 扫描报 I/O error rtk_btusb 驱动版本对 LE 命令支持不完整 不影响经典蓝牙,可尝试更新驱动或换用内核 btusb 模块

9. 参考资料


分享
LubanCat-3 (RK3576) 安装 Realtek RTL8851BU WiFi+蓝牙驱动全流程
https://asteriayx.github.io/embedded/lubancat3-rtl8851bu-wifi-bt-driver/
作者
yuxin
发布于
2026年8月6日
更新于
2026年8月6日
许可协议