9

I'm currently working on a C program in the LPCXpresso (eclipse-based) tool-chain on Windows 7, an IDE with gcc targeting the an NXP Cortex M3 microprocessor. It provides a simple way to compile-link-program the microprocessor over JTAG. The result of a build is an AXF file (ELF format) that is loaded by a debug configuration.

The loaded program resides in Flash memory from 0x00000 to 0x3FFFB. I'd like to include a 4-byte CRC-32 at 0x3FFFC to validate the program at start-up. I added another section and use the gcc __attribute__ directive to access that memory location.

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

To compute and store the CRC-32 value, my plan was to use SRecord with the following post-build steps:

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

This creates a binary with a checksum (necessary for bootloader) and then computes the CRC over the used Flash memory, storing the CRC value at 0x3FFFC.

However, I don't think I can load the binary file using the debugger. There is a built in programming utility with LPCXpresso that can load the modified binary file, however, that doesn't let me debug. I believe I can then try to start a debugging session with the original AXF file using "attach-only" mode, however, this becomes cumbersome.

I've been able to use readelf to inspect the crc32_build variable in the AXF file. Is there a way to edit the variable in the AXF file? Is there an industry-standard approach to inserting a CRC as a post-build step?

4

1 に答える 1

14

私が認識している業界標準はありません。これを行うには、さまざまな手法があります。を「C」のcrc32_buildan として使用し、リンカー スクリプトを介して定義することをお勧めします。extern例えば、

  $ 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 などの整合性チェックには重要ですが、単純なチェックサムには関係ありません。リンカー スクリプトを使用すると、領域の開始と終了の両方のシンボルを定義することもできます。スクリプトがなければ、エルフのイントロスペクションが必要です。

もちろん、このアイデアを拡張して、init データやその他の割り当てられたセクションを含めることもできます。ある時点で、使用objcopyしてセクションを抽出し、ビルド時に整合性チェックを行う必要があります。セクションにはさまざまなアライメントの制約がある場合があり、ビルド時のcrc計算を実行するときに、ホストでこれを (上記のphony.binで)模倣する必要があります。

おまけに、 srecファイル を生成すると、すべてがすでに完了しています。

に問題がある場合は、 ld.scriptsedawkperlpython--defsymなどで前処理し、テキストをCALC_CRCの 16 進値に置き換えることができます。

于 2014-06-11T14:57:05.493 に答える