一、 引言:系统底层的“供电死循环”

在嵌入式操作系统的移植过程中,网络通信模块的适配往往是检验底层驱动与上层框架协同能力的试金石。近期,在基于 RISC-V 架构的 Spacemit MusePaper2 开发板上进行 OpenHarmony 系统移植时,团队遇到了一个极其隐蔽的硬件级阻塞问题:WiFi 模块无法维持物理供电,导致网卡频繁离线,系统无法分配 IP 及完成基础的握手通信。

通过追踪内核启动日志(dmesg),我们捕获到了异常的根源。内核进程 spacemit-rf-pwrseq 陷入了高频的“断电-重启”死循环,WiFi 芯片(RTL8852BS)在刚触及电源的瞬间,便被系统底层的电源序列管理器强行切断。

由于该问题直接关乎硬件供电,单纯在用户态通过命令行重启网卡(如 rmmod/insmod)只能作为临时的带病运行方案。为了实现产品的稳定交付,团队决定深入 OpenHarmony 与 Linux 内核源码,开展一次外科手术式的全链路源码级重构。

二、 核心底层治理:彻底铲除硬件断电隐患

要解决 WiFi 模块的供电问题,必须从 Linux 内核驱动和设备树(Device Tree)双管齐下。

1. 内核驱动的防线:重构 spacemit-pwrseq.c

我们定位到负责射频电源序列的核心驱动文件:kernel/linux/spacemit_kernel-6.6/drivers/soc/spacemit/spacemit-rf/spacemit-pwrseq.c。分析源码发现,当底层产生状态冲突时,驱动会频繁调用 power_off 函数,导致 GPIO 管脚电平剧烈波动。

为了从根本上斩断这一逻辑链条,我们在 spacemit_power_on 函数的入口处植入了一段严格的拦截逻辑:

void spacemit_power_on(struct spacemit_pwrseq *pwrseq, bool on_off)
{
    // ==========================================================
    // 核心修改区域:物理供电强制拦截补丁
    // 如果系统发来的是断电指令 (on_off == false),直接假装成功并退出,
    // 彻底屏蔽 pwrseq 的高频断电死循环,强制 WiFi 供电管脚保持常亮状态。
    if (!on_off) {
        dev_info(pwrseq->dev, "HACKED: Bypass rf-pwrseq power off request!\n");
        return;
    }
    // ==========================================================

    mutex_lock(&pwrseq->pwrseq_mutex);
    // ... 后续原有上电逻辑
}

通过这段拦截代码,系统下发的任何非法断电指令都会被直接丢弃。这从物理层面解除了 WiFi 芯片无法维持供电的限制,确保了射频模块基础电压的绝对稳定。

2. 设备树驱动固化:k1-x_MUSE-Paper2.dts

内核逻辑修正后,我们需要在设备树中规范硬件的初始状态。我们修改了设备树文件 kernel/linux/spacemit_kernel-6.6/arch/riscv/boot/dts/spacemit/k1-x_MUSE-Paper2.dts,主要进行了两项关键操作:

  • 修正 GPIO 使能引脚:确保 wlan-pwrseq 节点调用原厂正确的供电管脚。

  • 注入电源常亮属性:添加了 keep-power-in-suspend 属性。这一修改彻底解决了系统在进入低功耗状态时 WiFi 模块发生物理掉电的问题,保障了设备唤醒后网络连接的连续性。

三、 上层业务打通:WiFi 服务的系统化构建

硬件供电的稳定仅仅是第一步。OpenHarmony 作为一个高度模块化的操作系统,要求必须将底层的 .ko 驱动与上层的用户态网络工具链紧密结合,才能实现开机即用的网络服务。

1. 初始化脚本注入:init.musepaper2.cfg

为了让系统在开机阶段自动完成 WiFi 环境的搭建,我们对 device/board/spacemit/musepaper2/cfg/init.musepaper2.cfg 进行了系统级修改。

首先,在 fs(文件系统挂载)阶段,配置了驱动自动加载及工作目录的创建:

"name" : "fs",
"cmds" : [
    "insmod /vendor/modules/8852bs.ko ifname=wlan0 if2name=p2p0",
    "mkdir /data/service/el1/public/wifi 0771 wifi wifi",
    "mkdir /data/service/el1/public/wifi/wpa_supplicant 0771 wifi wifi",
    "mkdir /data/service/el1/public/wifi/sockets 0771 wifi wifi"
]

随后,在 services 节点中,我们注册了 wpa_supplicant 为开机常驻服务,使其在后台自动接管 wlan0 的鉴权与连接逻辑:

"services" : [{
    "name" : "wpa_supplicant",
    "path" : ["/vendor/bin/wpa_supplicant", "-B", "-i", "wlan0", "-c", "/vendor/etc/wifi/wpa_supplicant.conf"],
    "uid": "wifi",
    "gid": ["wifi", "system"],
    "secon": "u:r:wpa_supplicant:s0"
}]
2. 工具链依赖注入:ohos.buildBUILD.gn

由于原生系统镜像缺失无线连接的管理工具,我们新增了 wifi_config/ 目录用于存放 wpa_supplicant.conf,并对构建配置文件进行了全局依赖注入。

device/board/spacemit/musepaper2/ohos.buildmodule_list 中,我们显式添加了依赖:

"module_list": [
    "//third_party/wpa_supplicant/wpa_supplicant-2.9_standard:wpa_supplicant",
    "//third_party/wpa_supplicant/wpa_supplicant-2.9_standard:wpa_cli",
    "//vendor/spacemit/musepaper2/wifi_config:wifi_config_file"
]

同步在 BUILD.gn 中添加打包规则。这确保了在执行全量编译时,编译器会将 wpa_supplicantwpa_cli 工具精准打包至 vendor/bin 目录下,彻底补齐了上层网络工具缺失的短板。

四、 构建环境排雷:build_kernel.sh 的修正

在整合上述全链路补丁并尝试进行全量编译时,团队遇到了构建系统卡死的问题。排查发现,原始的 device/board/spacemit/musepaper2/kernel/build_kernel.sh 脚本在拷贝内核源码时使用了带有软链接解引用参数的指令:

# 存在风险的原生逻辑
cp -rL ${KERNEL_SOURCE_DIR} ${KERNEL_BUILD_ROOT}

在庞大且存在大量架构层级软链接的 Linux 内核目录树中,cp -rL 会将所有的符号链接展开为实体文件,导致构建目录体积几何级膨胀,甚至引发拷贝死循环。我们将该函数修正为:

function copy_kernel(){
    rm -rf ${KERNEL_BUILD_ROOT}
    mkdir -p ${OHOS_SOURCE_ROOT}/out/kernel/OBJ
    echo cp -r ${KERNEL_SOURCE_DIR} ${KERNEL_BUILD_ROOT}
    cp -r ${KERNEL_SOURCE_DIR} ${KERNEL_BUILD_ROOT}
    cp -rf ${OHOS_SOURCE_ROOT}/device/board/${DEVICE_BOARD}/common/kernel_logo/kernel_logo_spacemit_0.ppm ${KERNEL_BUILD_ROOT}/drivers/video/logo/logo_linux_clut224.ppm
}

通过去除 -L 参数,保留了原始的符号链接结构,彻底扫清了内核全量编译过程中的构建障碍。

五、 编译验证与技术总结

所有代码合并完成后,我们执行了带 --ccache 参数的全量编译。将生成的固件烧录至实机并重启后,无需任何手动介入,系统后台已自动拉起网络服务。通过终端执行验证:

ps -ef | grep wpa

输出结果显示 wpa_supplicant 进程稳定驻留。随后通过 wpa_cli 成功连接测试热点,设备获取到了稳定的 IP 地址并成功 Ping 通外网,验证了本次适配的全面成功。

团队工程思考

本次 WiFi 模块的移植工作,是对 OpenHarmony 架构深度的一次全方位演练。我们深刻认识到:

  1. 硬件驱动的稳定性是一切上层业务的基石。面对底层的高频异常,必须深入 C 语言源码进行干预,而非在用户态寻找规避手段。

  2. 全链路思维的必要性。一个完整的外设支持,要求开发者打通从 C 源码(Kernel)、设备树(DTS)、系统配置(CFG)到构建脚本(GN/JSON)的完整闭环。

  3. 构建环境的严谨性。看似不起眼的文件拷贝指令,往往决定了大型工程 CI/CD 流水线的成败。

目前,这套 WiFi 源码修复补丁已稳定合入主线。后续我们将继续围绕该平台开展网络功耗调优,为 OpenHarmony 在 RISC-V 架构上的落地提供更坚实的支持。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐