LubanCat-2 (RK3568) Debian 下让 H3C Magic USB 无线网卡(AIC8800)联网全记录
作者:cedarQu
平台:LubanCat-2 V3(瑞芯微 RK3568)
系统:Debian GNU/Linux 12 (Bookworm)
内核:Linux 6.1.99-rk356x
日期:2026-09-09
一、问题背景
我在 LubanCat-2 板子的 USB 口上插了一个 H3C Magic 品牌的 USB 无线网卡,想在板子上通过它连接 WiFi。但是插上去之后,系统里根本找不到无线网卡接口(没有 wlan0),把设备认成了一个奇怪的"U 盘"。
这其实是一个非常典型、但容易被忽略的问题:这类网卡在出厂状态下会先枚举成"大容量存储设备(驱动盘)",里面装着 Windows 驱动安装程序 Setup.exe。 必须先把这块"驱动盘"弹出,网卡固件才会切换到真正的 WiFi 模式,然后系统才能把它当成无线网卡来用。
网上关于 AIC8800 芯片在 RK3568 上的移植资料零散不一,很多还停留在 Android / 5.10 内核时代。本文把从"插上网卡"到"稳定联网、重启自动生效"的完整链路记录下来,希望对同样用 RK3568 + AIC8800(AIC8800DC)USB 网卡的朋友有帮助。
二、确认硬件环境
先确认板子当前状态,跑最基础的一批命令:
bash
hostname # 主机名:lubancat
uname -a # Linux lubancat 6.1.99-rk356x #8 SMP ... aarch64
cat /proc/device-tree/model # EmbedFire LubanCat-2
查看 USB 设备与网络接口:
bash
lsusb
ip -br link
nmcli device status
关键发现(问题所在)
lsusb 里出现了这样一个设备:
Bus 003 Device 002: ID a69c:5726 aicsemi Aic MSC
注意看厂商 ID a69c(aicsemi,AiC 半导体),产品 ID 0x5726,产品字符串是 Aic MSC。MSC 就是 Mass Storage Class(大容量存储类)。也就是说系统把它识别成了 U 盘。
同时系统里没有任何无线接口:
lo dummy0 eth0 eth1 usb0 # 没有 wlan0
用 dmesg 看内核日志更是实锤:
usb-storage 3-1:1.0: USB Mass Storage device detected
scsi 1:0:0:0: Direct-Access AIC flash 1.0 PQ:0 ANSI:4
sd 1:0:0:0: [sda] Attached SCSI removable disk
这块"U 盘"大约 3.7MB,挂载后里面只有一个 Setup.exe(Windows 驱动安装器),以及 System Volume Information 目录。这就是网卡自带的"驱动光盘"。
系统里其实已经有固件和无线框架
继续查:
bash
ls /lib/firmware/ | grep aic # aic8800
ls /lib/firmware/aic8800/usb/ # aic8800, aic8800D80, aic8800D80X2, aic8800DC
ls /sys/module/ | grep -E "cfg80211|mac80211" # cfg80211 和 mac80211 已内置
结论:
- 内核里
cfg80211/mac80211无线框架已经编译进去了; - 系统镜像里甚至已经带了
aic8800的固件(/lib/firmware/aic8800/usb/...); - 但内核里没有任何 AIC8800 的驱动模块 (
/lib/modules/$(uname -r)/下找不到aic*.ko)。
所以:固件有、框架有、但没有"驱动"这个中间层,网卡自然只能以 U 盘模式存在。
三、把网卡从"U 盘模式"切换到"WiFi 模式"
这是整个移植最核心、最容易卡住的一步。
3.1 背后的原理
这类 AIC8800 USB 网卡的固件在设计上是"一卡两态":
- 出厂 / 上电状态 :枚举成一个只读的 FAT 大容量存储设备(vendor
0xA69C,product0x5726),里面放 Windows 驱动。这叫 MSC 模式 / 驱动盘模式。 - 正常工作状态 :一旦收到"弹出(eject)"指令,固件就会重新枚举 成一个真正的无线设备(vendor
0x368B,product0x88E3,接口类别0xFFVendor Specific)。这叫 WiFi 模式 / 运行模式。
所以"弹出 U 盘"这个动作不是简单卸载,而是切换网卡工作模式的开关。
3.2 手动弹出
先把挂载的"U 盘"卸载(它是只读挂载在 /media/usb0),然后对块设备执行 eject:
bash
sudo umount /media/usb0 2>/dev/null
sudo eject /dev/sda
lsusb 里的输出会立刻变化,等待几秒设备重新枚举后:
Bus 003 Device 003: ID 368b:88e3 AICSemi AIC8800DC
用 lsusb -v 看接口:
idProduct 0x88e3
iProduct 2 AIC8800DC
bInterfaceClass 255 Vendor Specific Class
此时设备已经从 0xA69C:0x5726(U 盘)变成了 0x368B:0x88E3(AIC8800DC 无线设备),接口类别是 0xFF,这才是驱动应该接管的状态。
3.3 注意
eject 实际返回过 unable to eject,但设备确实发生了重枚举------这说明 eject 指令被设备上的存储控制器"截获"并触发了模式切换。以 lsusb 结果为准即可。
四、选择并编译驱动
4.1 驱动芯片识别
设备重枚举后显示芯片为 AIC8800DC。我需要找到支持该芯片、且能编译到 6.1 内核的 Linux 驱动。
顺便用一条命令确认了驱动表里识别不到的 ID 问题:goecho 驱动的 USB ID 表里只有 0xA69C:0x88DC(AIC8800DC 旧 ID),并没有我们设备重枚举后的 0x368B:0x88E3。
4.2 仓库选择踩坑记录
我先后对比了两个开源仓库:
| 仓库 | 状态 | 结论 |
|---|---|---|
goecho/aic8800_linux_drvier |
星多,但主分支基于较旧内核 | 在 6.1 内核下编译报 cfg80211_ops 签名不匹配,需要大量 API 兼容改写 |
fqrious/aic8800-dkms |
明确做了多内核适配(覆盖 6.1 ~ 7.x) | 推荐,直接在 6.1.99 上编译通过 |
最终采用 fqrious/aic8800-dkms:
bash
cd /home/cat
git clone https://github.com/fqrious/aic8800-dkms.git
这个仓库的 src/ 下有两个模块:
aic_load_fw:固件加载助手,负责向芯片/系统提供固件路径、测试模式等符号;aic8800_fdrv:FullMAC 无线主驱动,真正创建wlan0的模块。
坑 :
aic8800_fdrv.ko依赖aic_load_fw.ko导出的get_fw_path、get_testmode、get_adap_test、aicwf_prealloc_txq_alloc等符号。单独加载aic8800_fdrv会报Unknown symbol!必须先编译并加载aic_load_fw。
4.3 给驱动打补丁:加入我们的设备 ID
原驱动 USB ID 表里只有 0xA69C:0x88DC,没有 0x368B:0x88E3。需要三处修改(以 src/aic8800_fdrv/ 为例):
① aicwf_usb.h:定义新设备 ID
c
#ifndef CONFIG_USB_BT
...
#else
#define USB_PRODUCT_ID_AIC8801 0x8801
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
#define USB_PRODUCT_ID_AIC8800D41 0x8d41
#define USB_PRODUCT_ID_AIC8800D83 0x8d83
#define USB_PRODUCT_ID_AIC8800D84 0x8d84
#define USB_PRODUCT_ID_AIC8800D85 0x8d85
#define USB_PRODUCT_ID_AIC8800DC_USB 0x88e3 // 新增:AIC8800DC USB 模式 ID
#endif
其中 USB_VENDOR_ID_AIC_USB = 0x368B 驱动里已有定义。
② aicwf_usb.c 的 aicwf_usb_chipmatch:把 0x88e3 识别为 AIC8800DC
在 pid == USB_PRODUCT_ID_AIC8800DC 分支后追加:
c
}else if(pid == USB_PRODUCT_ID_AIC8800DC_USB){
usb_dev->chipid = PRODUCT_ID_AIC8800DC;
AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__);
return 0;
}
③ aicwf_usb.c 的 aicwf_usb_id_table:加入匹配项
在 USB_PRODUCT_ID_AIC8800D85 条目后追加:
c
{USB_DEVICE(USB_VENDOR_ID_AIC_USB, USB_PRODUCT_ID_AIC8800DC_USB)},
因为设备接口类别是 0xFF,用 USB_DEVICE(...)(匹配任意接口)最稳妥。
4.4 固件路径处理
驱动加载固件时会把前缀路径 aic_fw_path 拼成 aic_fw_path/aic8800DC/<固件名>。系统里固件在 /lib/firmware/aic8800/usb/aic8800DC/,但驱动默认 aic_fw_path 为空。最简单做法:设成 /lib/firmware,并先确认 /lib/firmware/aic8800DC/ 下有固件(可以在 /lib/firmware/aic8800DC 放置/软链一份 DC 固件)。
在 src/aic8800_fdrv/rwnx_main.c 中:
c
char aic_fw_path[200] = "/lib/firmware"; // 原为空
module_param_string(fw_path, aic_fw_path, sizeof(aic_fw_path), 0644);
这样驱动最终从 /lib/firmware/aic8800DC/ 读取 fw_patch_8800dc_u02.bin、fmacfw_calib_8800dc_u02.bin、lmacfw_rf_8800dc.bin 等。请确认这些 DC 固件文件确实在该目录下。
4.5 编译
先编译 aic8800_fdrv:
bash
cd /home/cat/aic8800-dkms/src
make
再单独编译 aic_load_fw:
bash
cd /home/cat/aic8800-dkms/src/aic_load_fw
make
编译输出只有一条警告可以忽略:
warning: the compiler differs from the one used to build the kernel
The kernel was built by: aarch64-none-linux-gnu-gcc 10.3.1
You are using: gcc (Debian 12.2.0-14+deb12u1) 12.2.0
这是系统 gcc 12 与内核原始编译工具链 gcc 10 不同导致的,属于正常提示,不影响模块运行。生成两个 .ko:
src/aic_load_fw/aic_load_fw.ko
src/aic8800_fdrv/aic8800_fdrv.ko
五、加载模块
一定要先加载 aic_load_fw,再加载 aic8800_fdrv:
bash
cd /home/cat/aic8800-dkms/src
sudo insmod aic_load_fw/aic_load_fw.ko
sudo insmod aic8800_fdrv/aic8800_fdrv.ko
查看模块:
bash
lsmod | grep aic
# aic8800_fdrv 397312 0
# aic_load_fw 57344 1 aic8800_fdrv <-- 注意后面的 "1",表示被 fdrv 引用
查看网络接口:
bash
ls /sys/class/net/
# dummy0 eth0 eth1 lo usb0 wlan0 <-- wlan0 出现了!
dmesg 可以看到完整的固件加载和芯片初始化:
New interface create wlan0
get macaddr:70,8f
HT supp 1, VHT supp 1, HE supp 1
rwnx_interface_add: wlan0
netdevice: wlan0: ...
MAC 地址为 70:2a:d7:b2:63:8f,并且硬件支持 HT(WiFi 4)/ VHT(WiFi 5)/ HE(WiFi 6),说明 AIC8800DC 已经正常工作。
六、连接 WiFi 并验证上网
系统用的是 NetworkManager。确认设备被识别且射频未禁用:
bash
nmcli device status # wlan0 应显示 wifi,已断开
nmcli radio wifi # enabled
rfkill list # Soft/Hard blocked 都为 no
连接 WiFi(注意:普通用户没有 polkit 授权,要用 sudo 执行 nmcli):
bash
sudo nmcli dev wifi connect ysdlab password ysdlab123456
输出:
成功用 "wlan0939037ee-..." 激活了设备 ""。
查看连接状态和 IP:
bash
nmcli device status
# wlan0 wifi 已连接 ysdlab
ip -br addr show wlan0
# wlan0 UP 192.168.3.107/24
ip route
# default via 192.168.3.3 dev wlan0 ...
验证通过 wlan0 能上网
由于有线网 eth1 也在同一网段且 metric 更小(默认走有线),要专门验证走无线,用 --interface wlan0 绑定源接口:
bash
# 测试到网关
sudo ping -c 2 -I wlan0 192.168.3.3
# 测试外网
curl -s --interface wlan0 -m 5 -I https://www.baidu.com | head -n 3
# HTTP/1.1 200 OK
到这里,网卡已经成功连接上 WiFi,并能通过无线访问外网。
七、配置开机自动生效
如果只做上面六步,重启后一切都会失效:模块不会自动加载,网卡还会退回 U 盘模式。需要三处持久化配置。
7.1 把模块安装到系统并重建依赖
bash
cd /home/cat/aic8800-dkms/src
sudo mkdir -p /lib/modules/$(uname -r)/extra/aic8800
sudo install -m 644 aic_load_fw/aic_load_fw.ko aic8800_fdrv/aic8800_fdrv.ko \
/lib/modules/$(uname -r)/extra/aic8800/
sudo depmod -a
depmod -a 会扫描 modules.dep,识别出 aic8800_fdrv 依赖 aic_load_fw,这样 modprobe aic8800_fdrv 时就能自动带出 aic_load_fw。
7.2 开机自动加载模块
创建 /etc/modules-load.d/aic8800.conf:
bash
printf 'aic8800_fdrv\n' | sudo tee /etc/modules-load.d/aic8800.conf
7.3 开机自动弹出"U 盘"、切换到 WiFi 模式
这是最关键的一步。fqrious 仓库自带的规则只匹配 TPLink 的 0x5721,不匹配我们的 0x5726。手动创建一条规则:
bash
printf 'ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5726", RUN+="/usr/bin/eject /dev/%%k"\n' \
| sudo tee /etc/udev/rules.d/60-aic8800-usb.rules
然后重载:
bash
sudo udevadm control --reload-rules
sudo udevadm trigger
这条规则的作用:当检测到厂商 0xA69C、产品 0x5726 的大容量存储"磁盘"设备被添加时,自动对其执行 eject,从而立刻把网卡从 U 盘模式切换成 WiFi 模式。切换后设备重枚举为 0x368B:0x88E3,不会再命中这条规则,所以不会死循环。
7.4 WiFi 连接自动重连
NetworkManager 在 sudo nmcli dev wifi connect ... 时已经保存了一个名为 ysdlab 的 connection 配置,其 autoconnect 默认为 yes。开机后只要 wlan0 出现,NM 就会自动重连,无需额外操作。
八、完整流程回顾
上电/插卡
│
▼
设备枚举为 U 盘(0xA69C:0x5726, Aic MSC) ← 出厂默认
│
▼ udev 规则自动 eject
切换到 WiFi 模式(0x368B:0x88E3, AIC8800DC) ← 模块识别到该 ID
│
▼ aic_load_fw + aic8800_fdrv 加载
出现 wlan0,芯片初始化,加载固件
│
▼ NetworkManager 自动连接
连接 ysdlab,DHCP 获取 IP,访问外网
关键点总结:
- 先认清"这是 U 盘不是网卡" :
0xA69C:0x5726就是网卡的驱动盘态。 - eject 是模式开关 :必须把它从存储模式"弹出",才会以
0x368B:0x88E3重新枚举为无线设备。 - 驱动选型 :用支持 6.1 内核的
fqrious/aic8800-dkms,并对 USB ID 表打补丁。 - 模块依赖顺序 :
aic_load_fw→aic8800_fdrv。 - 固件路径 :把
aic_fw_path设为/lib/firmware,确保/lib/firmware/aic8800DC/下有固件。 - 权限 :
nmcli要sudo;eject也要sudo。 - 持久化 :模块装进
/lib/modules+depmod+modules-load.d+udev规则。
九、常见问题排查
Q1:insmod aic8800_fdrv.ko 报 Unknown symbol
A:aic8800_fdrv 依赖 aic_load_fw 的符号。先 insmod aic_load_fw.ko 再加载 fdrv。
Q2:lsusb 一直停在 a69c:5726 Aic MSC,看不到 WiFi 设备
A:eject 没生效,或系统把盘挂载了导致 eject 失败。先 umount 再 eject;确认用的是 /dev/sda 这类块设备。
Q3:nmcli dev wifi connect 报 Not authorized to control networking
A:普通用户没有 polkit 授权,加 sudo。
Q4:编译报 cfg80211_ops 签名不匹配
A:说明驱动版本面向旧内核。换用支持 6.1 的仓库(如 fqrious/aic8800-dkms),或对照内核头文件 include/net/cfg80211.h 里的 set_monitor_channel、set_tx_power、set_wiphy_params、start_radar_detection 签名改写驱动。
Q5:开机后网卡又变成 U 盘
A:udev 里没有自动 eject 规则,或 idProduct 没写对(要用 0x5726)。
Q6:cfg80211: failed to load regulatory.db 报错
A:只是缺监管数据库文件,不影响使用 WiFi,可忽略,或者安装 wireless-regdb。
十、结语
一个"插上就能用"的 USB 网卡,在嵌入式 Linux 上往往要先跨过"驱动盘模式"这道坎。AIC8800(AIC8800DC)这种"一卡两态"的设计,配合 RK3568 6.1 内核,关键在于:正确识别设备初始是 U 盘态 → 用 eject 切换到 WiFi 态 → 打上正确的 USB ID 补丁 → 正确加载依赖模块 → 用 NetworkManager 连接。
希望这篇记录能帮你少走弯路。如果设备型号不同(比如 AIC8800D80、AIC8800D81),只需在 USB ID 表里对应替换 0x88e3 即可,其余思路完全一致。