3、固件镜像格式:S19/HEX/BIN格式解析、镜像签名与校验、镜像加密原理

各位做ADAS量产的朋友,今天我们来聊聊固件镜像。这玩意儿看着不起眼,但搞不好能让你的产线直接停摆。我见过太多工程师在镜像格式上翻车了——烧进去的车载摄像头不工作,查了半天发现是S19文件解析错了地址。嗯,咱们今天就把这事彻底讲透。

3.1 三大镜像格式:S19、HEX、BIN

先说个基本概念。固件镜像说白了就是芯片要执行的二进制代码,但怎么组织这些代码,不同格式有不同玩法。ADAS系统里最常见的就是这三种:S19、Intel HEX、纯BIN。

3.1.1 S19格式(Motorola S-record)

S19格式在汽车电子领域用得特别多。我个人习惯用这个格式做量产烧录,因为它自带校验,省心。

一个典型的S19记录长这样:

S1137A00 48656C6C6F20576F726C642100 4A

我来拆解一下:

  • S1:记录类型。S1表示数据记录,S0是文件头,S5是记录计数,S9是结束记录
  • 13:字节长度(0x13 = 19字节,包含地址+数据+校验)
  • 7A00:起始地址(16位地址)
  • 48656C6C6F20576F726C642100:实际数据
  • 4A:校验和

关键点:S19的校验和是取反加一。计算方法是:把长度、地址、数据全部加起来,取低8位,然后取反加一。我当年调试一个ADAS雷达时,发现校验老报错,最后发现是工具链把S19的校验算法搞混了。

S19格式有几种变体:

类型 地址宽度 适用场景
S1 16位 小容量MCU,比如车身控制
S2 24位 中等容量,ADAS摄像头常用
S3 32位 大容量,比如域控制器

3.1.2 Intel HEX格式

Intel HEX是另一种主流格式。和S19比,它更灵活,但解析起来稍微麻烦点。

:10010000214601360121470136007EFE09D2190140

解析规则:

  • : 起始标记
  • 10:数据长度(16字节)
  • 0100:起始地址
  • 00:记录类型(00=数据,01=结束,02=扩展段地址,04=扩展线性地址)
  • 214601360121470136007EFE09D21901:数据
  • 40:校验和

避坑指南:我曾经遇到一个坑——Intel HEX的地址扩展记录。如果你的固件超过64KB,必须用04类型记录来扩展地址。有次产线烧录,工具没处理扩展地址,结果所有数据都写到了错误的位置。排查了整整两天。

3.1.3 纯BIN格式

BIN格式最简单,就是纯粹的二进制数据,没有地址信息,没有校验。你想想看,烧录器拿到BIN文件,只能从起始地址开始顺序写。

BIN的优缺点很明显:

  • 优点:体积最小,解析最快,适合量产
  • 缺点:没有地址映射,没有校验,出错很难排查

我个人建议:量产阶段用BIN,但开发调试阶段用S19或HEX。为什么?因为BIN出了问题你根本不知道数据写到哪去了。

3.2 镜像签名与校验

ADAS系统涉及安全,镜像签名是必须的。说白了,就是防止有人篡改你的固件。

3.2.1 签名流程

签名过程其实不复杂:

  1. 对固件镜像做哈希运算(SHA256或SHA512)
  2. 用私钥对哈希值加密,生成签名
  3. 把签名附加到镜像末尾,或者放在特定位置
// 伪代码示例
uint8_t firmware[] = { ... };  // 固件数据
uint8_t hash[32];              // SHA256哈希值
SHA256(firmware, sizeof(firmware), hash);

uint8_t signature[256];        // RSA签名
RSA_sign(private_key, hash, sizeof(hash), signature);

// 把签名附加到固件末尾
append_to_firmware(signature, sizeof(signature));

注意:签名用的私钥必须妥善保管。我见过一个项目,私钥直接硬编码在量产工具里,结果被逆向工程了。整个产线被迫停产,重新换密钥。

3.2.2 校验流程

芯片启动时,Bootloader会做校验:

  1. 读取固件数据,计算哈希值
  2. 读取签名,用公钥解密得到原始哈希
  3. 比较两个哈希值,一致则通过

这里有个细节:校验时机。我建议在烧录完成后立即做一次校验,芯片启动时再做一次。双重保险。

3.3 镜像加密原理

签名只能防篡改,不能防窃取。如果你的固件被读出来,别人照样能分析你的算法。ADAS的算法可是核心资产,必须加密。

3.3.1 对称加密 vs 非对称加密

类型 算法 速度 适用场景
对称加密 AES-128/256 固件本体加密
非对称加密 RSA/ECC 密钥交换、签名

实际量产中,我通常用AES加密固件,用RSA加密AES密钥。这叫混合加密,既安全又高效。

3.3.2 加密流程

// 1. 生成随机AES密钥
uint8_t aes_key[16];  // AES-128
RNG_generate(aes_key, sizeof(aes_key));

// 2. 用AES密钥加密固件
uint8_t encrypted_firmware[MAX_SIZE];
AES_encrypt(firmware, firmware_size, aes_key, encrypted_firmware);

// 3. 用RSA公钥加密AES密钥
uint8_t encrypted_key[256];
RSA_encrypt(public_key, aes_key, sizeof(aes_key), encrypted_key);

// 4. 打包:加密密钥 + 加密固件 + 签名

经验之谈:我曾经在量产工具里用了一个固定的AES密钥,结果被客户的安全审计发现了。后来改成每颗芯片单独生成密钥,虽然增加了复杂度,但安全性提升了一个量级。

3.3.3 解密流程

芯片端解密是反过来的:

  1. 用私钥解密得到AES密钥
  2. 用AES密钥解密固件
  3. 校验签名

这里有个性能问题。AES解密很快,但RSA解密很慢。如果每颗芯片都做RSA解密,产线节拍会受影响。我建议在量产工具端就完成解密,烧录时只烧录解密后的固件。但这样安全性会降低——你得确保产线环境安全。

3.4 量产中的实战建议

说了这么多理论,来点实际的。我在做ADAS量产工具时,总结了几个原则:

  • 格式统一:整个产线只用一种镜像格式,别混用。我推荐S19,因为地址信息完整,校验机制成熟
  • 签名必做:哪怕是非安全芯片,也建议做签名。万一哪天客户要求安全认证,你就不用返工了
  • 加密可选:如果固件不涉及核心算法,可以不做加密。加密会拖慢产线速度
  • 日志记录:每颗芯片的烧录日志都要保存,包括镜像哈希、签名值、烧录时间。出了问题好追溯

最后说一句:镜像格式、签名、加密,这三件事看起来是技术问题,其实是流程问题。把流程定好了,工具写好了,产线跑起来就很顺。我见过太多团队,技术方案很牛,但量产时各种掉链子。嗯,细节决定成败。