将CRC存储到AXF / ELF文件中

时间:2014-06-10 20:11:47

标签: c gcc arm crc lpc

我目前正在开发Windows 7上LPCXpresso (eclipse-based)工具链中的C程序,这是一个针对NXP Cortex M3微处理器的gcc IDE。它提供了一种通过JTAG对微处理器进行编译链接编程的简单方法。构建的结果是由调试配置加载的AXF文件(ELF格式)。

加载的程序驻留在闪存中,从0x00000到0x3FFFB。我想在0x3FFFC处包含一个4字节的CRC-32,以便在启动时验证程序。我添加了另一节,并使用gcc __attribute__指令访问该内存位置。

uint32_t crc32_build __attribute__ ((section(".text_MFlashCRC")));

为了计算和存储CRC-32值,我的计划是使用SRecord以及以下的构建后步骤:

arm-none-eabi-size "${BuildArtifactFileName}"
arm-none-eabi-objcopy -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin"
checksum -p ${TargetChip} -d "${BuildArtifactFileBaseName}.bin"
../util/srec_cat "${BuildArtifactFileBaseName}.bin" -binary -crop 0 0x3FFFC -fill 0xFF 0x00000 0x3FFFC -crc32-b-e 0x3FFFC -o "${BuildArtifactFileBaseName}.crc.bin" -binary
echo ""
echo "CRC32:"
../util/srec_cat "${BuildArtifactFileBaseName}.crc.bin" -binary -crop 0x3FFFC 0x40000 -o - -hex-dump

这将创建一个带校验和的二进制文件(引导加载程序所必需的),然后在使用的闪存上计算CRC,将CRC值存储在0x3FFFC。

但是,我不认为我可以使用调试器加载二进制文件。有一个内置的编程实用程序与LPCXpresso可以加载修改后的二进制文件,但是,我不能让我调试。我相信我可以尝试使用" attach-only"来启动与原始AXF文件的调试会话。然而,模式变得很麻烦。

我已经能够使用readelf来检查AXF文件中的crc32_build变量。有没有办法在AXF文件中编辑变量?是否有一种行业标准的方法来将CRC作为构建后步骤插入?

1 个答案:

答案 0 :(得分:3)

我不知道行业标准。有各种技术可以做到这一点。我建议您使用crc32_build作为extern在' C'并通过链接描述文件定义它。例如,

  $ cat ld.script
  .text : {
    _start_crc_region = .;
    *(.text);
    crc32_build = .;
    LONG(CALC_CRC);
    _end_crc_region = .;
  }

您为第一次调用传递值CALC_CRC为零,然后使用值集重新链接。例如,

 $ ld --defsym=CALC_CRC=0 -T ld.script *.o -o phony.elf
 $ objcopy -j sections phony.elf -o phony.bin # sections means checksum 'areas'
 $ ld --defsym=CALC_CRC=`crc32 phony.bin` -T ld.script *.o -o target.elf

我使用这种技术为图像添加数字签名;它应该同样适用于 crc 值。链接描述文件允许您定位变量,这对于像CRC这样的完整性检查通常很重要,但对于简单的校验和并不重要。链接描述文件还允许您为区域的开头和结尾定义符号。如果没有脚本,则需要一些 elf 内省。

您当然可以将想法扩展到包含 init数据和其他已分配的部分。在某些时候,您需要使用objcopy来提取节,并在构建时进行完整性检查。这些部分可能有各种对齐约束,您需要在执行构建时 crc 计算时在主机上模仿(在 phony.bin 上面)。

作为奖励,当您生成 srec 文件时,所有内容都已完成。

如果您遇到--defsym问题,可以使用 sed awk 预处理 ld.script perl python 等,并用 CALC_CRC 所在的十六进制值替换文本。