最近折腾了一块 Yuzuki Chameleon 开发板.
这块板子用的是全志 H616,板载一颗 XR829 WiFi/BT combo 芯片.出厂系统是 Tina Linux,4.9 内核,WiFi 和蓝牙都能用.但我不太能接受出厂系统里一些乱七八糟的问题,比如 USB 不正常,日志噪音大,整体状态比较脏.
所以我决定把它搬到主线内核上.
目标是 Linux 6.18.29.
这件事听起来很简单:
既然老系统里 WiFi 能用,那把驱动移植到新内核不就行了吗?
事实证明,不行.
这一路我踩了很多坑.比如一开始 WiFi scan 能 complete,但是一个 AP 都扫不到;后来发现中断脚 PG12 触发方式不对,引发中断风暴;XR829 需要 32.768KHz 低频时钟,而板子上并没有给它单独放 32K 晶振,需要 H616 从 PG10 输出;再后来 STA 能连上了,但一开 802.11n HT 模式,iperf 跑几十秒数据面就死;AP 模式也折腾了很多轮,最后发现固件里的 if_id 语义,probe response,RX filter 都有坑.
更离谱的是,我有一段时间以为自己一直在测试新驱动,结果实际加载的还是旧模块.
我把新的 xr829.ko 上传到了 `/lib/modules/6.18.29/updates/`,但系统真正加载的是 `kernel/drivers/net/wireless/...` 下面的旧模块.
也就是说,我有好几轮测试,根本没有测试到我刚改的代码.
这类嵌入式调试里的乌龙,非常真实,也非常浪费时间.
但这篇不是想展开讲 XR829 的全部技术细节.那些细节我会另写一篇博客.
这篇想说的是另一件事:
这次我很明显地感受到,AI 不是万能的.
而且不是我没试.
这次移植过程中,我几乎把手边能用的 AI 工具和模型都试了一圈:Codex,GPT 5.5,GLM5.1,Kimi 2.6,Deepseek V4 Pro以及其他一些 coding agent 和长上下文模型.
我的感受是:
它们都能帮忙,但都不能真正替我解决这个问题.
原因很简单,这类问题不是一道算法题,也不是一个孤立的编译错误.
它是一个巨大的混合系统问题:
SoC 的 GPIO,pinctrl,clock,SDIO host,WiFi 固件,WSM 协议,mac80211 KAPI,cfg80211 行为变化,加密 key path,rate control,AP/STA 并发,蓝牙 UART,共存机制,板级 RF 设计,全都可能有关.
任何一个方向都看起来合理.
AI 很擅长给出"可能性".
问题是,这里最不缺的就是可能性.
当 scan complete 但是扫不到 AP 时,AI 可以建议你查 32K,查 SDIO 电压,查 regdomain,查 GPIO reset,查 IRQ,查 RF 初始化,查 firmware,查 beacon filter.
这些建议不能说错.
但问题是,每一个建议背后都是一次真实实验:编译,上传,重启,等系统起来,加载模块,跑 scan,看日志.
我的板子只能通过串口操作,上传速度大概 10KB/s,一个模块几百 K,传一次就要一两分钟.再加上重启和测试,一个小实验三五分钟很正常.
AI 轻飘飘给出十个方向,人实际要烧掉一两个小时.
更麻烦的是,上下文一爆,AI 就容易失忆.
我明明已经测过 SDIO 25MHz,已经测过关 power save,已经测过禁用 BA,已经测过 HT20 long GI,已经测过 regdomain,已经验证过 32K,已经修过 IRQ 极性.
但一旦上下文太长,或者换一个模型,或者让 agent 重新接手,它又会重新建议:检查 SDIO 频率,确认 power save,regdomain,GPIO reset firmware.
这些建议不是垃圾,但在那个时间点已经没有价值.因为它不知道哪些路已经走死了.长期记忆也解决不了这个问题.
记忆可以记住"我在移植 XR829 到 Linux 6.18",可以记住"我发现 MCS0 稳定,MCS1+ 不稳定".但它不适合记住每一次实验的精确条件:
某一天晚上,ps_disable=1 加 firmware PS active,反向 iperf 20 秒仍然死;某一次禁用 TX BA,AMPDU 计数为 0,仍然死;某一次 HT20 + long GI,仍然死;某一次 runtime MCS mask 限制到 MCS0,连续一小时稳定.这不是"记忆",这是实验日志数据库.不得不感慨人脑RAG就是强哈.
AI 靠上下文硬背这类东西,很快就会乱.这次还有一个很典型的问题:AI 默认相信实验结果.比如我修改了代码,测试没变化.AI 往往会继续分析:那说明这个 patch 方向不对.但真实原因可能是:系统根本没有加载新模块.
这就是硬件 bring-up 和驱动调试里最危险的地方.
你以为你在验证假设 A,实际上你连测试对象都错了.
AI 不在现场,它不知道你的串口,文件系统,模块路径,启动脚本,modules.dep,旧 ko 残留,initramfs,udev,modprobe 优先级到底是什么状态.
它只能基于你给它的信息推理.
而嵌入式现场最常见的问题,恰恰是"你给它的信息本身就不可靠".
后来我慢慢调整了使用方式.
我不再问 AI:
XR829 scan complete 但扫不到 AP,帮我分析原因.
这种开放式问题很容易把搜索空间炸开.
我改成问:
"只比较 4.9 和 6.18 的 xradio_set_key(),找出 key install,tailroom,TX lock 相关差异.不要讨论 GPIO,SDIO,regdomain."
或者:
"我已经排除 power save,SDIO 频率,TX BA,HT40,short GI.现在只分析 MCS0 PASS,MCS1+ FAIL 可能涉及的 rate policy 数据结构.列出需要打日志的字段."
这样 AI 才比较有用.
它可以当代码阅读器,可以当 diff 助手,可以帮我整理调用链,可以帮我检查 patch 有没有明显破坏锁顺序,可以帮我把实验日志整理成表格,也可以提醒某些 mac80211 API 行为变化.
但它不能当主驾驶.
真正的方向判断,还是要人来做.
真正的实验设计,还是要人来压缩变量.
真正的现场验证,还是要人盯着串口,dmesg,iw,wpa_cli,iperf,/proc/interrupts 一点点确认.
这次最后能跑起来,不是因为哪个 AI 一下子猜中了根因.
而是靠大量无聊但必要的验证:
确认到底加载的是哪个 ko;
确认 IRQ 是否风暴;
确认 32K 是否输出;
确认 BT 固件下载是否稳定;
确认 STA 下 MCS0 和 MCS1+ 的差异;
确认 PTK 异常时广播和单播的行为;
确认 AP 模式下 AUTH response 为什么 TX fail;
确认固件 if_id 的实际语义;
确认 STA+AP 的启动顺序.
这些东西都没有捷径.
最后 XR829 在 Linux 6.18 上基本跑起来了:STA 可以用,AP 可以用,STA+AP 并发也能跑,BT 固件下载和 HCI 初始化也打通了.
但 HT MCS1+ 稳定性,WiFi/BT 共存里的瞬态 ping 丢包,仍然还有后续问题.
所以我的结论不是"AI 没用".
恰恰相反,AI 很有用.
但它有边界.
在复杂驱动移植里,AI 最适合做局部任务:
读代码.
找差异.
解释接口.
生成小 patch 草稿.
整理实验记录.
帮你发现可能遗漏的角落.
但它不适合在硬件 bring-up 阶段自由发挥.
因为这个阶段最重要的不是列出更多可能性,而是减少可能性.
AI 很容易扩大搜索空间.
人必须负责收敛搜索空间.
这也是我这次最大的教训:
不要把 AI 当成能替你完成复杂工程判断的东西.
它可以是很强的放大器.
但如果方向错了,它也只会把错误放大得更快.
AI 可以帮你走得更快.但你必须知道自己在往哪里走.
还有一个问题是:这件事几乎没有现成参考.
如果是常见芯片,比如 ath9k,iwlwifi,mt76,brcmfmac,网上有大量邮件列表,commit,bug report,厂商文档,用户踩坑记录.AI 至少还能从这些公开资料里总结出一些可靠方向.
但 XR829 不是这种情况.我能找到的公开资料里,没有一份真正可用的 XR829 到 Linux 6.18 主线内核的移植记录.唯一比较接近的是一份 5.15 UMAC 方向的代码,但它功能并不完整,STA 自己也不稳定,更不能作为金标准.这就很要命.因为 AI 的能力很大一部分来自已有资料的压缩,重组和推理.
当公开资料本身不存在,或者只有残缺的 BSP 代码,过时的 vendor driver,半成品移植和一些模糊日志时,AI 就没有可靠锚点.这时候它很容易按"正常 WiFi 驱动"的经验来猜.比如它会参考 CW1200 的逻辑,参考 mac80211 的通用流程,参考普通 SDIO WiFi 的 bring-up 经验.这些知识都不是错的,但 XR829 的真正问题恰恰在那些不通用的地方:固件私有 if_id 语义,WSM 命令细节,rate policy 编码,key install 时序,AP 模式 RX filter,BT 固件版本,WiFi/BT 共存行为.
这些东西没有文档.网上也没有现成答案,只有实测.
所以这次我最深的体会是:AI 在"已有知识的重组"上很强,但在"没有公开先例的硬件/固件黑盒问题"上,它很容易变成一个看起来很聪明的猜测机.
调试全过程查看原文链接.
夜雨聆风