项目 内容
文档版本 V1.0
目标平台 GK6780V100 / OpenHarmony 6.1
WiFi 模组 兆通微 9612U(USB 接口,WiFi + 蓝牙 combo)
厂商驱动包 ZTOP_ACEV100_Android16_wifi_bt_20260417171536_V312D

摘要

GK 平台系统由 OpenHarmony 5.1 升级至 6.1 后,原有 WiFi 模组驱动与框架接口发生较大变化。为满足无线网络连接及个人热点业务需求,项目选用兆通微 9612U USB WiFi 模组,基于厂商 ZTOP V312D 驱动源码完成内核模块编译、系统镜像集成及框架层适配。

本次适配依次攻克 HDF 设备注册、进程权限、热点 HDF 节点缺失、DHCP OFFER 报文不合规等问题,最终实现:STA 模式扫描/连接/DHCP/上网全流程贯通,以及系统级个人热点(SoftAP)多终端接入并自动获取 IP。本文档对调试过程、根因分析与修改方案进行系统归纳,供同类 USB WiFi 模组在 OH 6.1 上的移植参考。


1. 背景与目标

1.1 升级背景

OpenHarmony 6.1 相较 5.1,在 WiFi 子系统上主要变化包括:

  • HDF 设备模型:WLAN 能力通过libwifi_hdi_c_device.z.so、libwpa_hdi_c_device.z.so、libhostapd_hdi_c_device.z.so等 C 语言 HDI 设备对外暴露,由wifi_host等 Host 进程承载。
  • 服务分层wifi_manager_service负责上层业务;WPA/Hostapd 通过 HDF 接口与框架交互。
  • 组件演进:上游部分版本已移除独立 wifi_hal_service 二进制,目录创建等初始化逻辑需通过 init 配置保留,避免 WPA 框架依赖路径缺失。

在上述架构下,厂商 Linux 驱动需重新对接 nl80211/cfg80211,并完成 HDF、init、SELinux 等多层配置。

1.2 模组选型

属性 说明
型号 兆通微 9612U
接口 USB
能力 STA / AP 并发,支持 P2P 虚拟接口
驱动 ZTOP 系列,ztop_wifi_driver.ko + zt9612_fw.bin固件

1.3 验收目标

  1. 开机自动加载驱动,出现 wlan0(及 p2p0、wlan1等虚拟接口)。
  2. STA:扫描、连接、DHCP 获址、访问外网。
  3. SoftAP:系统设置中开启个人热点,手机可搜索、连接、通过 DHCP 获 IP 并上网。

2. 系统架构

个人热点与 STA 在 OH 6.1 上的主要调用关系如下:

说明:STA 走 wpa_interface_service + wpa_supplicant;SoftAP 走 hostapd_interface_service + 系统 dhcp_server,不再依赖独立的 dnsmasq手动方案(早期验证曾用手动 hostapd,最终交付以框架方案为准)。


3. 调试时间线

阶段 日期 日志目录 主要问题
WiFi 打开失败 05-12 log/hilog_6.1_wifi_open_fail01 ~ fail06 HDF 未注册、配置权限、CAP_NET_ADMIN
热点无法启动 05-18 log/hilog_6.1_softap_fail01 ~ fail03 hostapd_interface_service 未注册
关联后无 IP 05-18 ~ 05-20 log/hilog_6.1_softap_dhcp_fail01 ~ fail06 DHCP OFFER 报文非法
全链路通过 05-20 log/hilog_6.1_softap_dhcp_ok01 DISCOVER → OFFER → REQUEST → ACK 完整

4. 驱动编译与集成

4.1 环境准备

项目 配置
开发主机 Ubuntu 22.04
工具链 OHOS 6.1 LLVM(clang)+ 交叉编译前缀
内核 Linux 5.10(GK6780V100 OH 6.1 适配版)
驱动源码 厂商包解压至 ZTOP_V312D/wifi_driver/

4.2 编译脚本关键参数

修改 ZTOP_V312D/wifi_driver/build/build_linux.sh:

配置项 配置值 说明
KSRC {OHOS_ROOT}/out/kernel/OBJ/linux-5.10 须指向已编译内核树(含 .config、Module.symvers)
CROSS_COMPILE prebuilts/gcc/.../aarch64-linux-gnu- 交叉工具链前缀
Clang prebuilts/clang/ohos/linux-x86_64/llvm/bin/ LLVM 编译器路径
ANDROID 1 使能 Android 兼容宏,创建 p2p0 接口,避免 P2P 状态机异常

ANDROID=1同时影响厂商驱动中 AP 模式相关编译选项;ZTOP V312D 驱动默认编译完整 mac80211 栈并支持 NL80211_IFTYPE_AP;gk6780 平台编译时需保持 build_linux.sh gk6780 中 ANDROID=1(用于 p2p0 等接口)。ZTOP V312D 驱动源码中不存在 CONFIG_AP_MODE宏,AP 能力由内置 mac80211 栈默认提供。

4.3 编译与部署步骤

步骤 1:编译内核(生成模块依赖树)

cd {OHOS_ROOT}
./build.sh --product-name=gk6780v100 -T kernel

步骤 2:编译 WiFi 驱动

cd {OHOS_ROOT}/ZTOP_V312D/wifi_driver/build
sudo ./build_linux.sh gk6780

产物:build/output/ztop_wifi_driver.ko、fw/zt9612_fw.bin。

步骤 3:拷贝至 vendor 预置目录

cp build/output/ztop_wifi_driver.ko \
   vendor/goke/gk6780v100/wifi/firmware/ztop_wifi_driver.ko
cp fw/zt9612_fw.bin \
   vendor/goke/gk6780v100/wifi/firmware/zt9612_fw.bin

由 vendor/goke/gk6780v100/wifi/BUILD.gn 打包安装至镜像:

  • Ko:/vendor/etc/ko/ztop_wifi_driver.ko
  • 固件:/vendor/firmware/zt9612_fw.bin

步骤 4:Strip(可选)

$(CROSS_COMPILE)strip --strip-debug --strip-unneeded ztop_wifi_driver.ko

4.4 开机加载

在 device/board/goke/gk6780v100/tv/customize/gk6780v100/etc/vendor/init.taishan.cfg 的 boot job 中增加:

insmod /vendor/etc/ko/ztop_wifi_driver.ko

加载成功后 ifconfig -a 可见 wlan0、p2p0、wlan1 等节点(MAC 示例:60:58:01:xx:xx:xx)。


5. WiFi STA 功能调通(2026-05-12)

5.1 问题汇总

# 现象 根因 修复方案 关键证据
1 打开 WiFi 立即失败 wpa_interface_service 未写入 HDF 设备表 在 device_info.hcs 的 wlan::host 下增加 wpa_c_device,preload = 2 device wpa_interface_service not in configed device list
2 启动报 wifi_hal_service 无效 OH 6.1 镜像无 /system/bin/wifi_hal_service 删除 post-fs 中 start wifi_hal_service 及 services 定义;保留 early-boot 中目录创建命令 kmsg: ServiceStart pathArgs invalid
3 wpa_supplicant 无法读配置 wifi_host 进程缺少 wifi_group wifi_standard.cfg 为 wifi_manager_service 增加 wifi_group gid(与目录属组一致) Failed to open config file ... Permission denied
4 无法将 wlan0 置 UP wifi_host 缺少 NET_ADMIN / NET_RAW device_info.hcs 增加 caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH", "NET_ADMIN", "NET_RAW"] Could not set interface wlan0 flags (UP): Operation not permitted
5 启动早期 P2P 状态机报错 驱动未创建 p2p0 编译脚本设置 ANDROID=1 P2P state machine does not process messages: [200]

5.1.1 HDF 配置示例(wlan::host)

路径:vendor/goke/gk6780v100/hdf_config/uhdf/device_info.hcs

wlan :: host {
    hostName = "wifi_host";
    priority = 50;
    caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH", "NET_ADMIN", "NET_RAW"];
    gid = ["wifi_host", "wifi_group"];
    wifi_device :: device { ... wlan_interface_service ... }
    chip_device :: device { ... chip_interface_service ... }
    wpa_c_device :: device {
        device0 :: deviceNode {
            policy = 2;
            priority = 100;
            preload = 2;
            moduleName = "libwpa_hdi_c_device.z.so";
            serviceName = "wpa_interface_service";
        }
    }
    hostapd_device :: device { ... hostapd_interface_service ... }
}

说明:preload = 2(DEVICE_PRELOAD_DISABLE)表示设备进入 DevMgr 动态设备列表,框架在需要时通过 LoadDevice 加载;未配置则动态加载必然失败。

5.1.2 wifi_hal_service 处理说明

调试阶段发现 init 仍尝试启动已不存在的 wifi_hal_service 二进制。处理原则:

  • 保留 early-boot 中对 /data/service/el1/public/wifi、wpa_supplicant、sockets、dhcp 等目录的 mkdir 与 restorecon;
  • 移除对不存在二进制的 start 与 services 条目。

GK6780V100 产品另可通过 vendor/goke/gk6780v100/patch/foundation/communication/wifi/0008-support_dynamic_wifi.patch 扩展 HAL 层动态 insmod 能力;本案例最终采用 init.taishan.cfg 在 boot 阶段直接 insmod,与上述 patch 可并存,文档以实际生效的 init 加载路径为准。

5.2 STA 功能验证

测试项 操作 预期 结果(05-12 后)
扫描 进入设置 → 无线局域网,开启WiFi开关 列出周边 AP 通过
连接 选择目标AP,输入密码,点击连接 关联成功 通过
DHCP 框架自动 DHCP 获取有效 IP 通过
上网 ping 外网域名 连通 通过

6. 个人热点(SoftAP)调通(2026-05-18 ~ 05-20)

OH 6.1 个人热点由 hostapd(HDF)+ dhcp_server 实现,用户在设置中打开热点后,由 WifiApService 驱动完整状态机。

6.1 热点无法启动(05-18)

现象

设置中开启个人热点后很快关闭,其他设备扫描不到 SSID。

根因

WifiApService 通过 DevMgr 动态加载 hostapd_interface_service,但 GK6780V100 的 device_info.hcs 中:

  • 缺少 hostapd_interface_service 节点;或
  • moduleName 错误(如写成 libhostapd_interface);或
  • 未设置 preload = 2,不在动态设备列表内。

对比同平台已量产配置 vendor/goke/gk6320/hdf_config/uhdf/device_info.hcs,gk6320 在独立 hostapd::host 下正确声明了 libhostapd_hdi_c_device.z.so 与 preload = 2。gk6780v100 属于配置遗漏

关键日志

DevmgrServiceStubDispatchLoadDevice:load service hostapd_interface_service
device hostapd_interface_service not in configed device list
HdiStartAp: HdiApStart failed.
enter ApstartedState is failed.

修复

在 wlan::host(或独立 hostapd host,与产品策略一致)中增加:

hostapd_device :: device {
    device0 :: deviceNode {
        policy = 2;
        priority = 100;
        preload = 2;
        moduleName = "libhostapd_hdi_c_device.z.so";
        serviceName = "hostapd_interface_service";
    }
}

serviceName 与 HDI_AP_SERVICE_NAME 一致;moduleName 与 drivers/peripheral/wlan/hostapd 的 BUILD.gn 产物一致。

验证

热点可正常拉起,驱动日志可见 VIF 切换为 AP 模式(vif_type:3),wpa_supplicant 侧有 AP-STA-CONNECTED 等事件。


6.2 客户端关联但无法获取 IP(05-18 ~ 05-20)

本阶段为本次适配的核心难点:热点 SSID 可见、手机可关联并完成 WPA 四次握手,但始终拿不到 IP,一直重复 DHCP DISCOVER。

6.2.1 排查过程

排查手段 发现
hilog C01565 仅有 DISCOVER / OFFER,无 REQUEST / ACK
强制广播补丁后 broadCastFlag: 1 已生效,仍无 REQUEST
tcpdump / Wireshark OFFER 标记为 Malformed Packet;option 54 之后截断,缺少 END 0xff

6.2.2 根因与修复(三轮)

第一轮:DHCP 广播与选项基础修复

问题 根因 修复文件
单播 OFFER 手机收不到 SoftAP 接口上未强制广播 dhcp_s_server.cpp:IsWifiApInterface() + force broadcast
failed to create option node END_OPTION(255) 长度为 0 时 CreateOptionNode 拒绝 dhcp_option.cpp:允许 code=255 && length=0
giaddr 异常 客户端 giaddr=0 时仍填入网关地址 dhcp_s_server.cpp:FillReply 仅在收到非 0 giaddr 时回填
sendto 误判成功 使用 if (!ret) 将 -1 当作成功 改为 if (ret < 0)

修复后仍只有 DISCOVER/OFFER 循环,OFFER 长度仍为 304 字节。

第二轮:报文长度错误(决定性根因)

项目 错误值 正确值(RFC 2131)
DHCP_MSG_HEADER_SIZE
 
234 236(BOOTP 固定头至 options 前)
实际发送长度 304 = 234 + 70 306 = 236 + 4(magic cookie)+ 66(options 含 END)

ParseReplyOptions() 中 reply->length = DHCP_MSG_HEADER_SIZE + replyOptsLength 少算 2 字节,导致 sendto() 在 option 区尾部截断,DNS option(option 6)少发 1 字节且缺少 END,Wireshark 报 Malformed,手机丢弃 OFFER。

修复:

  • dhcp_message.h:#define DHCP_MSG_HEADER_SIZE 236
  • dhcp_s_server.cpp:ParseReplyOptions() 写入前检查 remainingSize,避免静默截断

第三轮:验证通过

成功日志(log/hilog_6.1_softap_dhcp_ok01):

Discover reply offer
send reply offer, length:306
==> Received DHCPREQUEST message.
Request reply ack!
send reply ack, size:306

手机获得 192.168.62.x 网段地址(以实际 dhcpd 配置为准),可正常上网。

6.2.3 DHCP 修复要点对照表

修改点 文件 作用
DHCP_MSG_HEADER_SIZE 236 dhcp_message.h 报文总长度与 RFC 一致
END option 零长度 dhcp_option.cpp 选项区合法结束
END 单字节 0xFF 写入 dhcp_s_server.cpp 符合 TLV 解析规则
giaddr 条件填充 dhcp_s_server.cpp 直连 SoftAP 场景 giaddr 保持 0
WiFi AP 强制广播 dhcp_s_server.cpp 提高 OFFER/ACK 到达率
sendto 返回值判断 dhcp_s_server.cpp 发送失败可感知

6.3 SoftAP 验证结果

验证项 操作 结果
热点可见 手机搜索 WiFi SSID 正常广播
连接 输入 WPA2 密码 关联成功
获 IP 查看手机网络详情 192.168.x.x(DHCP)
上网 浏览器访问外网 正常

7. 驱动层补充说明

7.1 P2P 接口与 ANDROID 宏

编译时未设置 ANDROID=1 时,驱动不创建 p2p0,wifi_manager_service 在启动早期向 P2P 状态机发送消息会失败,可能间接影响 SoftAP 并发或切换。设置后可见 p2p0 接口,P2P 相关告警消除。

7.2 AP 模式与 SoftAP 驱动侧说明

9612U 硬件支持 STA/AP 并发。本案例使用的 ZTOP V312D 驱动(ztop_wifi_driver.ko)无需、也不存在 CONFIG_AP_MODE 开关——该描述适用于其他厂商驱动(如 Realtek rtw_ap 方案),勿照搬。

ZTOP 驱动 AP 能力的实际来源如下:

机制 位置 说明
mac80211 全栈编译 wifi_driver/build/Makefile 中 MAC80211_COMPILE=1 默认编入 cfg.c、iface.c、tx.c 等,含 AP 相关逻辑
AP 接口类型注册 src/core/rwnx_main.c NL80211_IFTYPE_AP 已在 rwnx_limits 中声明
gk6780 编译参数 build/build_linux.sh → ANDROID=1 创建 p2p0、启用 android_if_*.c,与 P2P/接口创建相关
固件 zt9612_fw.bin 随 Ko 一并部署至 /vendor/firmware/

gk6780 平台编译命令:./build_linux.sh gk6780(须先完成内核编译)。产物拷贝至 vendor/goke/gk6780v100/wifi/firmware/ 后打包进镜像。

框架层 SoftAP 还需完成 HDF hostapd_interface_service 等配置(见第 6 章);驱动侧只要 Ko 能创建 AP VIF(日志中 vif_type:3)即可。本案例实测 SoftAP 已调通,说明当前预置 Ko 已具备 AP 能力,无需额外打开 CONFIG_AP_MODE。


8. 变更文件清单(附录 A)

子系统 文件路径 变更说明
HDF vendor/goke/gk6780v100/hdf_config/uhdf/device_info.hcs 补全 wlan/wpa/hostapd 节点、caps、preload
Init device/board/goke/.../init.taishan.cfg boot 阶段 insmod WiFi/BT Ko
WiFi 服务 foundation/communication/wifi/.../wifi_standard.cfg wifi_manager_service 增加 wifi_group
WiFi Init foundation/communication/wifi/.../wifi_hal_service.cfg 移除无效 wifi_hal_service 启动(调试方案)
DHCP foundation/communication/dhcp/.../dhcp_message.h DHCP_MSG_HEADER_SIZE → 236
DHCP foundation/communication/dhcp/.../dhcp_option.cpp 允许 END_OPTION 零长度节点
DHCP foundation/communication/dhcp/.../dhcp_s_server.cpp 广播、giaddr、长度、sendto 等修复
Vendor vendor/goke/gk6780v100/wifi/BUILD.gn 预置 Ko 与固件
Vendor vendor/goke/gk6780v100/wifi/firmware/* ztop_wifi_driver.ko、zt9612_fw.bin 等
驱动源码 ZTOP_V312D/wifi_driver/build/build_linux.sh KSRC、工具链、ANDROID=1
可选 Patch vendor/goke/gk6780v100/patch/.../0008-support_dynamic_wifi.patch HAL 动态 insmod(产品可选)

9. 经验总结

9.1 关键成果

  • 在 OH 6.1 上完成兆通微 9612U 驱动编译、镜像集成与框架适配。
  • STA 模式:扫描、连接、DHCP、上网全流程可用。
  • SoftAP:系统级个人热点可被发现、连接,客户端 DHCP 完整交互(OFFER 306 字节 / ACK 306 字节)。

9.2 OH 6.1 WiFi 模组适配 Checklist

  1. HDF 三件套:wlan_interface_service、wpa_interface_service、hostapd_interface_service 均需注册,动态加载须 preload = 2。
  2. wifi_host 权限:caps 含 NET_ADMIN、NET_RAW;gid 含 wifi_group;配置目录属主与进程 gid 一致。
  3. init 与上游差异:确认 wifi_hal_service 二进制是否存在,勿启动无效服务;保留 data 分区目录初始化。
  4. 驱动编译:gk6780 须用 ./build_linux.sh gk6780 且 ANDROID=1(p2p0);ZTOP 驱动 AP 由 mac80211 默认支持,无 CONFIG_AP_MODE。
  5. DHCP:SoftAP 场景用 Wireshark 校验 OFFER 长度与 option 完整性;DHCP_MSG_HEADER_SIZE 必须为 236。
  6. SELinux:失败时优先检索 avc: denied(本次以权限与 HDF 为主,SELinux 为辅助排查项)。

 


10. 参考日志目录

完整调试日志位于工程log/ 目录:

  • hilog_6.1_wifi_open_fail01 ~ fail06 — WiFi 打开(05-12)
  • hilog_6.1_softap_fail01 ~ fail03 — 热点启动(05-18)
  • hilog_6.1_softap_dhcp_fail01 ~ fail06— DHCP 问题(05-18 ~ 05-20)
  • hilog_6.1_softap_dhcp_ok01 — 最终通过(05-20)

文档结束

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐