nrf51 DFU Bootloader – Mind the Gap(s)

I came up with a clever way to allocate manage persistent logs in flash via GNU linker files. This method was working great without softdevice / bootloader... but when flashing via DFU (with the appropriate memory map) my custom linker section was being mangled.

The key was that only my section was failing. The .text section was located properly and the application was running. I use the ALIGN() macro in the linker file to align my section on a flash page boundary and then objcopy to generate ihex from elf. The alignment offset was large enough that objcopy decided to save a bit of space by putting a gap in the ihex file

e.g.

:1081600036373839616263646566000000000000DC
:1084000000C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF

The address space above is not contiguous; it jumps from 0x18170—0x18400. This is a perfectly valid thing to do in an ihex file and all the tools I've ever used handled this without issue...

I noticed that my section (after loading via bootloader) was landing at 0x18170... which is familiar. It's the first address of the gap. After consulting the objcopy man page, the --gap-fill flag can be used to insert a fixed value into the gap areas. After filling the gap, the code works as expected.

This means the DFU bootloader from SDK 6.1 is very stupid. I haven't checked the source; but seems to load the firmware at a fixed address; stripping all the addressing prefixes from the transferred file.

A project for a rainy day is to improve this code and/or take a look at bootloaders from subsequent SDKs. Anywho, if your bootloaded application isn't where you expected it'd be; it may be worth checking that your hex file is contiguous. This nugget would've saved me 3 hours.