Position Independent Code on STM32 - pointers

168 views Asked by At

I've managed to build and run position independent code on STM32. Vector table and GOT are patched. Everything works, but I have problem with such code.

double myAdd(double x) {
   return x + 0.1;
}

double (*ptrmyAdd)(double) = &myAdd;

char* myString = "foo bar";

int main() {
   ...
   printf("%s %2.2f\n", myString, ptrmyAdd(0.1));
   ...
}

I works only when application has no offset (relative to flash base address). Reason is obvious, myString and ptrmyAdd points to .rodata and .text without proper offset.

What can I do? I can reinitialize pointers at runtime.

int main() {
   ...
   myString = "foo bar";
   ptrmyAdd = &myAdd;
   printf("%s %2.2f\n", myString, ptrmyAdd(0.1));
   ...
}

And it works fine with any offset.

To fix pointers which points to .rodata I can spare some RAM and move .rodata to RAM, but I can't move .text to RAM.

I can also run through section .data at startup and update all values which looks like flash addresses, but it's dangerous.

Is there any way to fix those pointers before main()?

Why I need position independent code. System looks like this...

*--------*
|        |
|        |
|  APP2  | Application bank 2
|        |
|        |
*--------* 0x08084000
|        |
|        |
|  APP1  | Application bank 1
|        |
|        |
*--------* 0x08008000
|        |
|  INFO  | Application info area
|        |
*--------* 0x08007800
|        |
|  LDR   | Bootloader area
|        |
*--------* 0x08000000

Bootloader downloads application image via y-modem protocol to first avaliable bank marked as "not active". Bootloader sets new bank as "active" and "valid" and previous "active" bank as "not active". After reset bootloader start application from "active" bank. Before application starts, bootloader activates IWDG.

If reset was from IWDG, bootloader checks "not active" bank for valid application. If it contains "valid" application, bootloader marks active bank as "invalid" and swaps active banks.

User performing an update doesn't know which bank is free. Bootloader decides which bank to use.

0

There are 0 answers