zephyrrtos.cnZephyr 生态 · 中国驱动软件系统
RK3588 · AMP 异构 · A/B 自回滚

RK3588 AMP 开发环境

场景:要在 RK3588 上做 **A 核 Linux + 实时域 Zephyr** 的异构开发——内核、设备树、guest 镜像、内核模块四类产物天天改, 而每一次改动都可能让板子起不来、或起来但门铃不响。这种活儿最容易的失败方式不是写错代码,而是把板子试挂了却回不去。 所以这套环境的核心不是「能跑 AMP」,而是:实验怎么试、失败怎么回、结论怎么证。

当前实测:Radxa ROCK 5B+(RK3588)· 内核 6.1.75-abdbg · 运行分支 debug(A/B 武装,abcount 自动记账)· Zephyr guest 由 ATF 经厂商 rockchip,amp 路径在 A55 core3(MPIDR 0x300)启动

环境构成

板卡Radxa ROCK 5B+(Rockchip RK3588):4×Cortex‑A76 + 4×Cortex‑A55,NPU 6 TOPS;eMMC 系统盘 + 2×NVMe 组 RAID1(/mnt/raid1,复位不丢的归档区)
Linux 侧Armbian(aarch64),内核 6.1.75-abdbg(自定义调试分支),厂商 AMP 支持;设备树经 /boot/debug/dtb/rockchip/ 加载
Zephyr 侧最小 Zephyr 镜像(zephyr-amp.bin),由 ATF 经厂商 rockchip,amp 路径在 A55 core3 上启动;A 核与实时域通过共享内存 + 门铃协作
启动/停止 guest/sys/rk_amp/boot_cpu:echo on/off [cpu id] > /sys/rk_amp/boot_cpu,echo status [cpu id] 查状态。每次开机只有一次 CPU_ON 有效——想重试就重启
内核模块ndp_cons(控制台/门铃侧),必须在启动 guest 之前装载,否则 mailbox 被别的驱动先占
证据归档板子 RAID 的 /mnt/raid1/shared/ab-boot-docs/:文档、日志、状态快照、脚本(INDEX.md 记录近 8000 个文件);ab-docs-sync 定时同步

A/B 双分支武装:让「试挂了」可逆

板子有两条启动分支:stable(稳定产物)与 debug(实验产物)。所有实验只动 debug 分支,且由启动器自动记账回滚:

武装 / 回滚ab-ctl use-debug 武装实验分支 → reboot;ab-ctl use-stable 立即回稳定分支;touch /boot/ab-off 急停(持久禁用 debug)
启动账本U-Boot 把本次启动的分支与计数写进 /proc/cmdline 的 absrc/abcount/abmax/ablast;abtag 打印分支证明
成功判定ab-boot-ok.service 在启动约 +75 s 记账、约 +199 s 判「健康」并清零 abcount;在此之前重启会被算作失败
自动回滚连续失败 3 次(abmax=3)即自动切回 stable 并持久禁用 debug 分支——不需要人守着
失败演练ab-test-reboot.service(disabled 状态,只在演练回滚时临时开)
为什么重要内核/DTB 一改就可能起不来,而这块板子没有串口;自动回滚是唯一的「兜底通道」,也是敢每天做实验的前提
纪律(违反就会白跑一轮):两次实验间隔 > 75 s;abcount 到 2 时再失败一次就自动回滚,先把根因想清楚再动手; 起来后先 abtag + ab-ctl status 核验,不对劲就 use-stable 回退再定位,不要在 debug 分支上连续试错。

四类产物,与「部署生效」的两把尺

内核源码 /mnt/raid1/shared/linux-rockchip(需 CONFIG_ROCKCHIP_AMP=y)→ /boot/debug/{Image, System.map-*, vmlinux-*, uInitrd},重启生效
设备树arch/arm64/boot/dts/rockchip/rk3588-radxa-rock-5b+.dtb(源在 rk3588-radxa-rock-5b-ndp.dtsi,不改 blob)→ /boot/debug/dtb/rockchip/,重启生效
Zephyr guestzephyr_ndp/tests/amp_bringup → /boot/debug/zephyr-amp.bin,每次开机 echo "on 0x300" > /sys/rk_amp/boot_cpu 拉起
ndp_cons 模块就地 insmod,立即生效;必须在启动 guest 之前接管 fec60000.mailbox

每类产物覆盖前都留 <文件>.pre-<tag>-<epoch> 备份——回退就是把备份改回原名,不需要重新构建。
而「部署生效」不用嘴说,用两把尺:

# 尺一:载入字节 == 文件(uio 只能 mmap,read() 只给中断计数)
#   取 /dev/uio1 前 4 KiB 的 md5,与 /boot/debug/zephyr-amp.bin 同段 md5 比对
# 尺二:跑的代码 == 这一版(guest 自报 build id)
cat /sys/module/ndp_cons/parameters/pcm | grep '^id:'
两个坑:uio 设备只能 mmap,用 dd/cat 自证会得到假阴性; 启动脚本里载入 amp 镜像的那句 load … 失败不报错,所以「没换」永远静默——必须靠两把尺。

边界与已知限制

无串口本机没有串口控制台:早期启动挂死不会自愈(系统看门狗只在 systemd 武装后生效,约 boot 12 s)。证据只能靠 /var/lib/ab-boot/history.log、ab-ctl journal、/var/lib/systemd/pstore/
非干净复位会丢写ext4 commit=120:拔电/硬复位会丢最近约 120 s 的写入。所以唯一一份源码与证据绝不放在 / 或 /home,母本必须在 RAID
AMP 在线时别跑重活「AMP 数据面在线 + 重构建/重 I/O」已两次导致无现场复位(无 panic、无 pstore);空载跑 10 分钟不复现,AMP 不在线时构建也不复现。要做重活先停 guest 并重启
判定要满足前置模块没装载时不能断言「数据面不动」;guest 没启动时不能断言「门铃不通」——先核验前置条件
guest 每次开机只有一次机会CPU_ON 只有一次有效,guest 停掉后要重试只能重启板子
文档与代码目前是私有的两个源码仓库与 RAID 文档都在工作组内部;需要账号或会员访问。本页只公开方法与边界

起不来 / 起来不对怎么办

先分两条线① 网络:本板走 WiFi,重启后 DHCP 可能要几分钟,期间 ping 与 22 都不通——别当挂死处理;② 真挂:journalctl --list-boots 多出启动、boot_id 变化
被自动回滚了?看 ab-ctl status 的 ablast 与 ab-ctl journal;回滚后 debug 分支被持久禁用,定位完再 use-debug 重新武装
起来了但门铃不响先确认 ndp_cons 已装载、guest 已 status 为 on、中断线出现在 /proc/interrupts(rockchip-amp)
文件全变 NUL / insmod 报 Invalid ELF header magic典型的非干净复位损坏:从 RAID 归档恢复母本,不要试图修补
问智能体 Zephyr 问题问答 · 直接问智能体