Reputation: 19
I am trying to create a position independent binary for a Cortex-M0+ using the ARM GNU toolchain included with Atmel Studio 7 (arm-none-eabi ?). I have looked many places for information on how to do this, but am not successful. This would facilitate creating ping-pong images in low-high Flash memory areas for OTA updates without needing to know or care whether the update was a ping or pong image for that unit.
I have an 8 kB bootloader resident at 0x0000 which I can communicate with over UART and which will jump to 0x6000 (24 kB) after reset if it detects a binary there (i.e. not 0xFFFF erased Flash). This SAM-BA bootloader allows me to dump memory and erase and program Flash with .bin files at a designated address.
In the application project (simple LED blink), doing nothing but adding -section-start=.text=0x6000 to the linker command line results in the LED blink code working after it is programmed at 0x6000 by the bootloader. I see also in the hex file that it starts at 0x6000.
In my attempt to create a position independent binary, I have removed the above linker item, and added the -fPIC flag to the command lines for the compiler, the linker and the assembler. But, I think I still see absolute branch addresses in the disassembly, such as :
28e: d001 beq.n 294
And the result is that the LED blink binary I load at 0x6000 does not execute unless I specifically tell the linker to put it at 0x6000, which defeats the purpose. Note that I do also see what looks like relative branches in other parts of the disassembly :
21c: 4b03 ldr r3, [pc, #12] ; (22c )
21e: 58d3 ldr r3, [r2, r3]
220: 9301 str r3, [sp, #4]
222: 4798 blx r3
The SRAM is always at the same address (0x20000000), I just need to be able to re-position the executable. I have not modified the linker command file, and it does not have section for .got (e.g. (.got) or similar).
Can anyone explain to me the specific changes I need to make to the compiler/assembler/linker flags to create a position independent binary in this setup ? Many thanks in advance.
Upvotes: 1
Views: 387
Reputation: 1789
You need to look more closely at your disassembly. For 0xd001, I get this:
0x00000000: d001 .. BEQ {pc}+0x6 ; 0x6
In your case, the toolchain has tried to be helpful. Clearly, a 16 bit opcode can't encode an absolute address with a 32 bit address space. So you are closer than you think to a solution.
Upvotes: 0