Files
story/docs/device-firmware-ab-protocol.md

7.7 KiB

设备A/B分区固件升级与启动确认协议

1. 目的与适用边界

本协议用于把云端已经完成的签名制品、灰度命令和阶段回执,与量产终端常见的A/B双分区升级机制对齐。它定义设备必须持久化的升级状态、云端可观察阶段、启动健康窗口和自动回退结果,但不替代具体芯片、Bootloader、分区表、看门狗或厂商烧写SDK。当前cmd/sim-device实现的是协议级模拟器,用于在真机到位前发现状态机和联调问题;是否能安全写入真实分区、断电后继续启动及由Bootloader自动回退,仍必须在量产候选硬件上验收。

旧设备不声明或不启用A/B能力时继续使用既有downloading → installing → confirmed/failed链路。A/B模拟器只有在SIM_FIRMWARE_AB_UPDATE=true且提供绝对路径SIM_FIRMWARE_STATE_FILE时启用,不改变设备v2既有必填字段和命令终态。

2. 设计原则

  1. 设备只信任安全存储或受控镜像预置的厂商公钥,不信任升级命令携带的公钥。
  2. 制品大小、SHA-256和Ed25519签名全部通过后,才允许写入非活动分区。
  3. 任何时刻都不得直接覆盖当前活动且已确认可启动的分区。
  4. 设置下次启动分区和健康截止时间前,必须先持久化升级日志;云端回执不得先于本地耐久状态。
  5. 新分区只有在核心进程、配置读取、设备身份和必要外设健康检查通过后才能确认。
  6. 健康检查失败或超过截止时间时,由设备/Bootloader回到旧分区,并向云端提交带回退事实的稳定失败终态。
  7. 设备重启后可重新拉取仍为ACKNOWLEDGED的同一命令;云端增加投递次数但不把状态回退到DELIVERED。

3. 设备侧状态机

stateDiagram-v2
    [*] --> StableA: A分区已确认
    StableA --> Downloading: 收到firmware_update
    Downloading --> ArtifactVerified: 摘要和签名通过
    Downloading --> Failed: 下载/摘要/签名失败
    ArtifactVerified --> StagedB: 写入并校验非活动B分区
    StagedB --> RebootPending: 持久化启动尝试和健康截止时间
    RebootPending --> BootVerifyingB: 重启进入B分区
    BootVerifyingB --> StableB: 健康检查通过并确认B
    BootVerifyingB --> RolledBackA: 健康失败或超时
    RolledBackA --> Failed: 上报已自动回退
    StableB --> [*]
    Failed --> [*]

当活动分区为B时,下一次升级使用完全对称的B→A流程。power_loss_after_stage保留STAGED日志,重启后从设置启动分区继续;power_loss_during_boot保留REBOOT_PENDING日志,后续启动继续执行健康检查。重复执行必须针对同一命令编号、版本、发布编号和摘要,任一不一致都以LOCAL_UPDATE_STATE_CONFLICT停止,不能覆盖未知的在途升级。

4. 本地耐久日志

模拟器状态文件只保存非敏感升级元数据,权限为当前进程可读写。字段如下:

字段 含义
phase STAGED、REBOOT_PENDING、CONFIRMED或ROLLED_BACK
command_id、release_id 绑定当前可靠命令和云端发布记录
target_version、previous_version 目标版本和回退基线版本
sha256 已验证制品摘要,用于重启后核对同一升级意图
active_slot、previous_slot、target_slot 当前稳定分区、回退分区和待启动分区
boot_attempt_id 每次设置下次启动分区时生成的随机启动尝试编号
health_deadline 新分区必须完成健康确认的UTC截止时间
updated_at 最近一次耐久更新时刻

CONFIRMED和ROLLED_BACK记录作为下一次升级的本地稳定基线保留。量产实现应把等价数据写入具备掉电保护的Bootloader环境区或专用元数据分区,并使用冗余、校验和或事务写策略处理半写入,不能直接照搬普通文件实现。

5. 云端回执与主状态映射

命令仍只使用ACKNOWLEDGED、SUCCEEDED和FAILED三类状态。A/B细节放在可选result_summary中,云端将所有设备侧写入、重启和健康确认阶段保持为firmware_assignment.status=INSTALLING,避免扩展既有主状态枚举破坏客户端兼容。

回执阶段 命令状态 分配主状态 建议进度 关键字段
downloading ACKNOWLEDGED DOWNLOADING 5—100 result_code、verified_sha256
installing ACKNOWLEDGED INSTALLING 80 INSTALL_STARTED
staging ACKNOWLEDGED INSTALLING 85 active_slot、target_slot
reboot_pending ACKNOWLEDGED INSTALLING 90 boot_attempt_id、boot_health_deadline
boot_verifying ACKNOWLEDGED INSTALLING 95 active_slot、previous_slot
confirmed SUCCEEDED CONFIRMED 100 installed_version、active_slot
rolled_back FAILED FAILED 95 rollback_applied=true、rollback_version、failed_slot

启动失败回退示例:

{
  "status": "FAILED",
  "result_summary": {
    "phase": "rolled_back",
    "progress_percent": 95,
    "result_code": "BOOT_HEALTH_FAILED_ROLLED_BACK",
    "rollback_applied": true,
    "active_slot": "A",
    "failed_slot": "B",
    "rollback_version": "0.2.0-sim",
    "boot_attempt_id": "<随机编号>"
  }
}

回退已经保护设备可启动性,但目标版本未成功,因此云端仍把命令和分配标记为失败、把批次暂停并停止扩量。运营页面从last_result展示非活动分区写入、等待重启、健康确认或已自动回退,不把“回到了可用旧版本”误报成升级成功。

6. 模拟器参数和故障注入

参数 默认值 作用
SIM_FIRMWARE_AB_UPDATE false 显式启用A/B升级协议
SIM_FIRMWARE_STATE_FILE 无 A/B耐久日志绝对路径;启用时必填
SIM_FIRMWARE_ACTIVE_SLOT A 首次运行且没有稳定日志时的活动分区,只允许A/B
SIM_FIRMWARE_CURRENT_VERSION 0.2.0-sim 首次运行的回退基线版本
SIM_FIRMWARE_BOOT_HEALTH_WINDOW 2m 启动健康窗口,范围1秒至30分钟
SIM_FIRMWARE_FAULT=power_loss_after_stage 无 写完非活动分区后模拟掉电,保留STAGED
SIM_FIRMWARE_FAULT=power_loss_during_boot 无 新分区健康确认时模拟掉电,保留REBOOT_PENDING
SIM_FIRMWARE_FAULT=boot_health_failed 无 模拟新分区健康失败并自动回退

7. 轻量纵向验证

powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\smoke-sim-firmware.ps1 -Mode ABRollback

脚本创建一个临时签名版本和单设备批次。第一次运行下载、验签、写入B分区并持久化REBOOT_PENDING,断言云端为ACKNOWLEDGED/INSTALLING/90/REBOOT_ARMED;第二次运行模拟B分区健康失败,断言本地回到A分区、原版本恢复,云端收敛为FAILED/FAILED/95/BOOT_HEALTH_FAILED_ROLLED_BACK,批次暂停且观察设备为0。结束后精确清理数据库、对象存储、固件文件和本地状态文件。

同一脚本还生成独立的firmware-device-evidence-v1设备侧证据,读取包含7条去重阶段事件的云端批次响应,并调用cmd/firmware-conformance核对命令、发布、启动尝试、制品摘要、签名密钥、阶段顺序、时间相关性、分区和回退版本。证据字段及报告归档规则见固件真机联调一致性证据采集与校验说明。

该结果证明协议和云端状态闭环可联调,不证明真实Bootloader、闪存掉电一致性或真实外设健康检查已经通过。真机验收仍须覆盖至少3台量产候选终端、A→B和B→A、写入中断电、首次启动断电、健康超时、看门狗复位、连续升级、云端暂停和已验证版本回滚。