LubanCat-2 (RK3568) Debian 下让 H3C Magic USB 无线网卡(AIC8800)联网全记录

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 网卡的固件在设计上是"一卡两态":

  1. 出厂 / 上电状态 :枚举成一个只读的 FAT 大容量存储设备(vendor 0xA69C,product 0x5726),里面放 Windows 驱动。这叫 MSC 模式 / 驱动盘模式。
  2. 正常工作状态 :一旦收到"弹出(eject)"指令,固件就会重新枚举 成一个真正的无线设备(vendor 0x368B,product 0x88E3,接口类别 0xFF Vendor 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,访问外网

关键点总结:

  1. 先认清"这是 U 盘不是网卡" :0xA69C:0x5726 就是网卡的驱动盘态。
  2. eject 是模式开关 :必须把它从存储模式"弹出",才会以 0x368B:0x88E3 重新枚举为无线设备。
  3. 驱动选型 :用支持 6.1 内核的 fqrious/aic8800-dkms,并对 USB ID 表打补丁。
  4. 模块依赖顺序 :aic_load_fw → aic8800_fdrv。
  5. 固件路径 :把 aic_fw_path 设为 /lib/firmware,确保 /lib/firmware/aic8800DC/ 下有固件。
  6. 权限 :nmcli 要 sudo;eject 也要 sudo。
  7. 持久化 :模块装进 /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 即可,其余思路完全一致。

相关推荐
迪康Defender13 小时前
终端安全实践:浅谈端点安全管理系统内置终端防火墙能力
运维·服务器·网络·经验分享·安全·php·终端安全管理
I'm a winner13 小时前
《AI 赋能嵌入式开发:从 0 到全栈工程师》模块1|第3课时
人工智能·嵌入式硬件
AI备忘录13 小时前
(二十二)华为华三锐捷迈普思科 802.1X 端口认证配置命令(网络准入五厂商对照)
运维·服务器·开发语言·网络·安全·华为
the3clipse13 小时前
MacOS、Linux 与 Windows 视频编解码对比:AV1、HEVC、ProRes 与硬件加速优劣势
linux·windows·macos·hevc·av1·视频解码·硬件解码
优化Henry13 小时前
LTE站点以太网光模块告警处理实践
运维·网络·笔记·学习·信息与通信
s65166549613 小时前
bootsect.s,setup.s,head.s的主要功能和对系统状态的影响、作用
linux
明王明王13 小时前
PVE 上用 SPICE:统一连接 Debian、Arch 和 Windows 11 桌面
运维·windows·debian
数字新视界13 小时前
2026机房动环监控选型指南:场景规模需求、市场发展占有率和竞争梯队报告解析
大数据·运维·网络·人工智能·嵌入式硬件·机房动环监控·机房环境安全
夜雪一千13 小时前
Python URL解码详解:单层、双重URL解码实战与踩坑指南
linux·服务器·python
程序员_小兵13 小时前
PCIe Switch Fabric 技术解析
服务器·c语言·嵌入式硬件·php·fabric