LPC MCUs and ELF manipulation
Patch LPC firmware ELF for checksum.
01. LPCs and vector checksum
After playing with NXP LPC series MCUs for some while, something has bothered me: Verification of program flash against ELF files always fail.
Hmmm.. That's strange. Tried a few different LPC models, and the failure position is always 0x1C. After digging into the user manual, I found out these MCUs uses the reserved 0x1C vector as a checksum for the first 8 vectors. The bootloader sums up the first 8 words, and if the result is zero, the flash content is considered as valid and bootloader will jump to the application reset vector.
Different IDEs and tools reacts differently to this hardware feature, for example, IAR will compute this checksum by the linker during link stage, and the final image or hex files will contain correct contents. J-Link and OpenOCD process this checksum beforee flashing the image to target MCUs, regardless what the original image has.
However, this checksum machnism causes a problem when verifying the flash content against original ELF files, since the original file still contains invalid value for the checksum field, which will incremential download the first flash sector even if the application has no changes.
02. ELF Patching
Since I already know how the checksum is computed, the next thing is to find a way patching the ELF image, writing the correct checksum into the specified offset in interrupt vector table. Instead of grepping and using some regex magic, I decided using libelf
from elfutils
to manipulating the section data.
The documentation for libelf
is too brief to give me the instructions on how to modify the content of a specific section. After several hours of searching between mailing lists and with the help of an old book, I finally get the library working:
((uint32_t *)ivt_data->d_buf)[7] = checksum;
It is important to use MMAP
commands, which will modify the data in-place without touching other section information (Since we only modify one word).
Elf *e_handle = elf_begin(elf_fd, ELF_C_RDWR_MMAP, NULL);
The ELF will be modified in-place, which can be successfully verified by J-Flash.
The code is published at GitHub.
03. References
[1]:https://sourceforge.net/projects/elftoolchain/files/Documentation/libelf-by-example/
[3]: https://www.nxp.com/webapp/Download?colCode=UM10850 (Sign in required)