摘要
在 Android 14 + Linux 6.1 的移植过程中,RTL8822CE Wi‑Fi 很容易出现一种“硬件已经被 PCI 枚举到,但系统就是没有wlan0”的尴尬状态。本文复盘一次完整的 RTL8822CE 适配过程,最终定位出两个连续阻塞点:第一,目标内核虽然已经带有rtw8822ce驱动源码,但实际刷入的内核配置没有启用RTW88_8822CE;第二,驱动启用后又卡在标准rtw88固件请求失败,而设备镜像中的固件目录和命名方式与rtw88驱动的预期不一致。文章给出完整的定位思路、修复方法、adb 验证方式以及最终成功扫描 AP 的结果,适合做 Android 平台无线移植、内核升级和 Realtek Wi‑Fi 适配时参考。
关键词
Android 14、Linux 6.1、RTL8822CE、Realtek Wi‑Fi、rtw88、cfg80211、mac80211、firmware_class.path、Wi‑Fi HAL
一、问题现象
最初现象并不是“系统完全看不到设备”,而是一个更容易误判的问题:
- PCI 总线已经能看到
10ec:c822这张无线网卡。 - Android 框架侧却没有出现可用的
wlan0。 - Wi‑Fi 开关尝试打开时,框架层出现
Failed to start vendor HAL一类错误。
这一类问题非常容易把人带偏到 HAL、权限、supplicant 或者 framework 逻辑,但实际上最先应该确认的,是内核驱动有没有真正绑定到设备。
二、第一步不要猜,先看运行边界
这次排查最关键的一点,是没有一上来就改 framework,而是先把控制路径切成三层:
- PCI 设备是否已经枚举。
- 内核驱动是否已经绑定。
- Android 框架是否已经拿到无线接口。
运行态检查结果非常清晰:
10ec:c822已经作为 PCI 无线设备枚举。- 系统没有
wlan0。 - 设备对应的 PCI function 处于
no-driver状态。
这说明问题首先不在 Android 上层,而在“驱动没有接管硬件”这一层。
三、第一层根因:内核里有源码,但配置没有打开
继续检查目标 Linux 6.1 内核树,可以发现:
rtw88子系统已经存在。rtw8822ce.c也已经存在。- PCI ID
0xC822的支持已经写在驱动表里。
也就是说,源码不是缺失状态,问题出在配置没有启用。
运行内核配置进一步验证了这个判断:
CONFIG_CFG80211=yCONFIG_MAC80211=y- 但没有
CONFIG_RTW88、CONFIG_RTW88_8822CE
于是第一层修复就很明确了:
CONFIG_RTW88=y CONFIG_RTW88_8822CE=y重新走一遍olddefconfig后,依赖会自动展开成:
CONFIG_RTW88_CORE=y CONFIG_RTW88_PCI=y CONFIG_RTW88_8822C=y CONFIG_RTW88_8822CE=y这一步完成后,新内核再次启动时,rtw_8822ce已经开始对10ec:c822进行 probe。
四、第二层根因:驱动起来了,但标准固件请求失败
驱动被打开之后,问题并没有直接结束,而是推进到了下一层:
rtw_8822ce 0003:31:00.0: Direct firmware load for rtw88/rtw8822c_fw.bin failed with error -2 rtw_8822ce 0003:31:00.0: failed to request firmware rtw_8822ce 0003:31:00.0: failed to load firmware这说明驱动已经在工作,但它找不到自己需要的固件。
继续看驱动源码,可以发现rtw88对 RTL8822CE 的固件请求名是标准 Linux 命名:
rtw88/rtw8822c_fw.bin rtw88/rtw8822c_wow_fw.bin而设备原始镜像中已有的却是厂商风格命名,例如:
rtl8822c_fw rtl8822e_8822c_fw这两套命名并不兼容,因此驱动自然找不到文件。
五、第三层根因:固件路径也不是你以为的那个目录
如果只看到“找不到固件”,很多人第一反应是把文件放到/vendor/firmware。但这次排查还有一个非常关键的细节:
内核命令行中明确指定了:
firmware_class.path=/vendor/etc/firmware这意味着内核 firmware loader 的实际搜索基路径不是常见的/vendor/firmware,而是:
/vendor/etc/firmware也就是说,即使你已经把标准rtw88固件推到了/vendor/firmware/rtw88/,驱动仍然会报-2,因为它根本不会去那个目录找。
这一步是整个适配过程中最容易踩的坑之一。
六、真正让 RTL8822CE 起飞的关键修复
到这里,RTL8822CE 真正成功工作的修复链条就完整了:
1. 打开内核配置
在目标 Linux 6.1 内核配置中启用:
CONFIG_RTW88=y CONFIG_RTW88_8822CE=y2. 刷入包含rtw_8822ce的新 boot
重新编译并刷入 boot 后,驱动会开始 probe10ec:c822。
3. 把标准 rtw88 固件放到正确目录
需要准备的文件是:
rtw88/rtw8822c_fw.bin rtw88/rtw8822c_wow_fw.bin注意放置路径不是/vendor/firmware/rtw88/,而是:
/vendor/etc/firmware/rtw88/只有这样,request_firmware()才能成功命中。
4. 重新触发驱动 probe 或直接重启
固件到位后,可以重新触发 PCI 设备 probe,或者直接重启系统。完成后,日志会从“固件加载失败”变成真正加载成功。
七、成功后的关键日志和状态长什么样
当固件路径和驱动配置都正确后,RTL8822CE 的日志会明显跨过之前的失败点,出现类似:
rtw_8822ce 0003:31:00.0: Firmware version 9.9.15, H2C version 15 rtw_8822ce 0003:31:00.0: Firmware version 9.9.4, H2C version 15与此同时,运行态可以看到:
wlan0 phy#1这说明无线接口已经真正被创建出来,内核侧 bring-up 已经完成。
八、为什么一开始 Android 还在报Failed to start vendor HAL
这也是一个很容易被误判的现象。
前面的日志里,Android 框架层确实出现过:
WifiVendorHal: Failed to start vendor HAL WifiNative: Failed to start Hal WifiSelfRecovery: Triggering recovery for reason: WifiNative Failure但这批失败并不是最终的 HAL 架构问题,而是驱动和固件没准备好时,Wi‑Fi 框架早期启动留下的旧失败记录。
当 RTL8822CE 驱动真正起来、wlan0出现后,再重新 enable Wi‑Fi,框架状态就发生了实质变化:
Current wifi mode: EnabledState mClientInterfaceName: wlan0 mIfaceIsUp: true这说明之前的 HAL 启动失败,根本原因仍然是更下层的内核/固件问题,而不是 framework 自身逻辑失效。
九、最终功能验证:不只是接口出来了,而且已经能扫到 AP
真正判定 Wi‑Fi 成功,不能只看wlan0是否存在,还要看无线功能是否真的工作。
这次最终做的验证是主动发起扫描,结果已经返回了周围 AP,例如:
CU_kUCx_5G CU_kUCx 我爱创达 CU_Z86p CBN-LH70E9这说明 RTL8822CE 已经完成了以下闭环:
- PCI 枚举正常。
rtw_8822ce驱动绑定成功。- 标准固件加载成功。
wlan0接口创建成功。- Android Wi‑Fi Client mode 启动成功。
- 无线扫描能力正常。
到这里,RTL8822CE Wi‑Fi 可以认定为已经成功工作。
十、适配这类 Realtek Wi‑Fi 时最值得记住的几点经验
1. “设备已枚举”不等于“驱动已工作”
PCI 上看到10ec:c822,只能说明硬件被发现了,不能说明 Wi‑Fi 已经可用。一定要继续看有没有驱动绑定、有没有wlan0、有没有phy。
2. 有驱动源码不等于配置已经打开
很多移植问题不是缺代码,而是代码在树里、配置没启。先确认Kconfig/Makefile和运行中的config.gz,能省掉大量无效怀疑。
3. 固件名和固件路径要同时核对
只核对“有没有固件文件”是不够的,还要确认:
- 驱动请求的名字是什么。
- 内核实际使用的 firmware search path 是什么。
这次就是标准rtw88固件名和firmware_class.path=/vendor/etc/firmware叠在一起,导致问题被放大。
4. Android 上层失败不一定是上层本身的问题
Wi‑Fi HAL、supplicant、wificond 报错时,不要立刻把锅甩给 framework。很多时候,根因仍然在更下层的驱动和固件准备阶段。
十一、总结
这次 RTL8822CE Wi‑Fi 适配成功的核心结论可以总结为一句话:
让 RTL8822CE 真正工作,不仅要在 Linux 6.1 内核里启用RTW88_8822CE,还必须为标准rtw88驱动提供它真正能找到的固件文件和正确目录。
前者解决的是“驱动有没有机会接管硬件”,后者解决的是“驱动接管硬件后能不能完成 bring-up”。两者缺一不可。
如果后续要做长期可重复的镜像方案,建议把RTW88_8822CE的内核配置和标准rtw88固件部署一起固化进正式构建流程,而不是每次刷机后依赖手工 adb 补文件。这样后续不论是量产、测试还是回归验证,都会稳定得多。