4. 生成签名镜像
任务目标
在Zephyr固件升级流程中,镜像必须经过签名才能被bootloader验证并加载。本案例使用imgtool工具对编译生成的应用程序镜像(zephyr.bin)进行签名,输出带签名头和元数据的可升级bin文件,该文件可直接用于MCUboot的串口或DFU升级。
环境准备
本案例假设已完成以下前置条件:
- 已编译生成Zephyr应用程序镜像
build/zephyr/zephyr.bin(未签名原始镜像) - 已生成MCUboot签名密钥对(如
root-rsa-2048.pem),若未生成可执行:
imgtool keygen -k root-rsa-2048.pem -t rsa-2048
签名命令与参数说明
使用imgtool sign命令对镜像签名,核心参数含义如下:
--key:指定私钥文件路径--align:镜像写入flash的对齐方式,Zephyr默认通常为8--version:镜像版本号,格式为major.minor.revision,升级时版本号必须递增--slot-size:每个slot的flash大小,需与设备flash分区匹配(如0x10000表示64KB)--header-size:镜像头大小,需与bootloader配置的CONFIG_BOOT_HEADER_SIZE一致,常见为0x200(512字节)
完整实现
以下命令对zephyr.bin进行签名,生成可直接用于升级的signed.bin文件:
# 进入Zephyr构建目录
cd build/zephyr
# 使用imgtool签名(以RSA-2048密钥、8字节对齐、64KB slot为例)
imgtool sign \
--key ../../root-rsa-2048.pem \
--align 8 \
--version 1.0.0 \
--slot-size 0x10000 \
--header-size 0x200 \
zephyr.bin \
signed.bin
若需同时生成十六进制格式(用于直接烧录到primary slot),可追加--hex-addr 0x10000参数(地址需与设备flash布局匹配):
imgtool sign \
--key ../../root-rsa-2048.pem \
--align 8 \
--version 1.0.0 \
--slot-size 0x10000 \
--header-size 0x200 \
--hex-addr 0x10000 \
zephyr.bin \
signed.hex
验证方法
签名完成后,通过以下方式确认镜像已正确签名:
- 检查文件大小:
signed.bin应比原始zephyr.bin大约多出header-size(0x200字节)加上签名和元数据长度(RSA-2048签名约256字节)。执行ls -l zephyr.bin signed.bin对比大小差异。 - 查看镜像信息:使用
imgtool info命令读取签名镜像的头信息,确认版本号、对齐方式等参数正确写入:
imgtool info signed.bin
预期输出应包含类似以下内容(具体数值取决于签名参数):
Image header:
magic: 0x96f3b83d
version: 1.0.0
align: 8
slot size: 65536
...
- 升级验证:将
signed.bin通过MCUboot支持的传输方式(如UART使用mcumgr或dfu-util)发送至设备secondary slot,重启后bootloader应验证签名并完成镜像切换。若签名无效或版本不递增,bootloader将拒绝升级并回退到当前镜像。
常见问题
- 对齐错误:若
--align与设备flash写入粒度不匹配,bootloader会报错。Zephyr默认使用8字节对齐,若使用外部flash可改为--align 8或按实际配置调整。 - 版本号不递增:MCUboot要求新镜像版本高于当前运行版本,否则会拒绝升级。每次生成升级包时需递增
--version。 - header-size不匹配:若签名时指定的
--header-size与bootloader编译时的CONFIG_BOOT_HEADER_SIZE不一致,会导致镜像无法被正确解析。需检查设备树或bootloader配置确认实际值。