0

I am trying to insert a md5 hash of part of my binary into the binary, for keeping track of MCU FW version.

I have approached it like this: in the link script I have split the flash in two sections

MEMORY                                                                                                  
{                                                                                                       
FLASH0 (rx)      : ORIGIN = 0x8000000, LENGTH = 64K - 16                                                
FLASH1 (r)       : ORIGIN = 0x800FFF0, LENGTH = 16                                                      
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 8K                                                       
} 

Then I have specified a output section like so:

  .fw_version :                                                                                         
  {                                                                                                     
    KEEP(*(.fw_version))                                                                                
  } >FLASH1

Next I have my firmware_version.c file containing only:

#define FW_VERSION_SIZE 16                                                                              

const unsigned char FW_VERSION[FW_VERSION_SIZE]                                                         
  __attribute__((section(".fw_version"), used)) = {0};

Then after the binary is compiled and objcopy has been used to create a .bin file I have a 65536 B large file, I split that file at 65520 bytes, do a md5 checksum of the first part and insert that into the second part (16 B). Lastly I do cat parta partb > final.bin.

When i examine this binary with hexdump I can see that the md5 checksum is indeed at the end. Using objdump -h I get:

...
8 .fw_version   00000010  0800fff0  0800fff0  00017ff0  2**2
...

and objdump -t gives:

...
0800fff0 g     O .fw_version    00000010 FW_VERSION
...

I thought that this meant that I could just use FW_VERSION[i] to get part i of the md5 checksum from within the mcu fw but when I examine the memory in gdb I get that it's all zeroed out like it was never changed.

What am I missing here?

[edit] the device is a stm32f030c8t6 arm cortex m0 programmed through gdb.

evading
  • 3,032
  • 6
  • 37
  • 57
  • What's the device and how are you programming the code into the chip? – Jon May 08 '15 at 09:06
  • Your comment made me realize that while I have modified the .bin file I load the unmodified .elf file with gdb. – evading May 08 '15 at 09:38

1 Answers1

0

Like I commented under the question I found that the (one) reason for it not working was that while I was manipulating the .bin file while I loaded the .elf file when programming with gdb. It should (could) have worked if I used a programmer or bootloader to download the .bin file to the target.

I found a better (I think) way of doing it though.

  1. Compile all the sources in the project to .o files.
  2. cat *.o > /tmp/tmp.something_unique. I used $(shell mktemp) in the Makefile
  3. openssl dgst -md5 -binary /tmp/tmp.something_unique > version_file
  4. objcopy -I binary -O elf32-littlearm -B arm version_file v_file.o
  5. linkscript has a section .fw_version : { KEEP(v_file.o(.data)) } >FLASH1
  6. link application
  7. in application get the address of the version number by doing extern unsigned char _binary_version_file_start; uint8_t *FW_VERSION = &_binary_version_file_start; const size_t FW_VERSION_SIZE = (size_t) &_binary_version_file_size;. Note that the uses of & are correct.

This will result in the checksum being taken over all the objects that are compiled from source and then this checksum is linked into the binary that is flashed in the target.

evading
  • 3,032
  • 6
  • 37
  • 57