0

I have built firmware for stm32f4, so I have *.elf an *.bin files. If I load *.bin file into internal flash it runs correctly. But if I want load this firmware to another address different from default (0x08000000) and run it from my bootloader, of course it does not works. I fix memory area address in project settings (I use CooCox 1.7.6 if it matter) and it begins runing from the bootloader.

I don't want rebuild project every time I load firmware in standalone mode or using bootloader. So I'm looking for method that will allow me to make *.bin files from *.elf, which will be able to load from the different addresses.

I tried manualy interupt vector table fixing. It allow me to run small blinker project but it doesn't work for more complex projects. I must be missing something.

Then I tried objcopy with --change-addresses but unfortunately it doesn't work. I get the same file without any difference.

I think, it is a general problem and there are solution for it but I must be missing something important.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Konstantin T.
  • 994
  • 8
  • 22
  • If I had a nickel for every time we answered this question. Please see all the prior answers to this question...What you are looking for is position independent code PIC -fpic or some such option if you are using gcc, and there is work on your part to repopulate/adjust the global table once relocated. or you could just link for the correct address and not have to deal with it... – old_timer Apr 04 '18 at 12:29
  • @old_timer Thank you for your reply! – Konstantin T. Apr 05 '18 at 07:41
  • That would be a tough to do that. It would be more of making sure any interrupts and jumps are well taken care of. I would suggest to look at some other similar answers here. – Dheeraj Kumar Apr 06 '18 at 14:03
  • What is the point? – 0___________ Apr 06 '18 at 23:46
  • @old_timerit will not work I afraid. Library functions are not relocable and you need different startup codes. I do not see the reason of it. – 0___________ Apr 06 '18 at 23:49

3 Answers3

1

You have to compile your code as position independent. See the -fpic and -fPIC options of gcc. Or you need a loader that understands the relocation table of the ELF image.

Xypron
  • 2,215
  • 1
  • 12
  • 24
1

I just happened to complete an odyssey on STM32 Cortex-M4 (and M0) with Position-Independent Code firmware images operated by a bootloader. I will give you and overview and link the full article below. My evaluation board is NUCLEO-L432KC with target MCU STM32L432KCU6U. The magic goes like this:

On high level, there are couple of things needed:

A very simple bootloader. It only needs to read 2 4-byte words from the flash location of the firmware image. First is stack pointer address and second is Reset_Handler address. Bootloader needs to jump to Reset_Handler. But as the firmware is relocated further in the flash, the Reset_Handler is actually a bit further. See this picture for clarification:

So, bootloader adds the correct offset before jumping to Reset_Handler of the firmware image. No other patching is done, but bootloader (in my solution at least) stores location and offset of the firmware image, calculates checksum and passes this information in registers for the firmware image to use.

Then we need modifications in firmware linker file to force the ISR vector table in the beginning of RAM. For Cortex-M4 and VTOR (Vector Offset Table Register) the ISR vector table needs to be aligned to 512 boundary. In the beginning of RAM it is there naturally. In linker script we also dedicate a position in RAM for Global Offset Table (GOT) for easier manipulation. Address ranges should be exported via linker script symbols also.

We need also C compiler options. Basically these:

-fpic

-mpic-register=r9

-msingle-pic-base

-mno-pic-data-is-text-relative

They go to C compiler only! This creates the Global Offset Table (GOT) accounting.

Finally we need dedicated and tedious assembly bootstrap routines in the firmware image project. These routines perform the normal startup task of setting up the C runtime environment, but they additionally also go and read ISR and GOT from flash and copy them to RAM. In RAM, the addresses of those tables pointing to flash are offset by the amount the firmware image is running apart from bootloader. Example pictures:

I spent last 6 months researching this subject and I have written an in-depth article about it here:

https://techblog.paalijarvi.fi/2022/01/16/portable-position-independent-code-pic-bootloader-and-firmware-for-arm-cortex-m0-and-cortex-m4/

E_net4
  • 27,810
  • 13
  • 101
  • 139
-1

I do not think so that would work well in your case because when you are compiling the file to run with boot loader, you also needs to make sure that Interrupt vector also have been moved to the new location else there will be a problem in executing some of the functions.

Dheeraj Kumar
  • 377
  • 2
  • 13
  • Thank you for your reply! Moving interupt vector is not a big problem. Fixing addresses in vector table too, because it has fixed position. AIK there are `SHT_RELA` and `SHT_REL` section in elf file wich has to help to relocate it. I think it may help but it doesn't exist in my elf files. – Konstantin T. Apr 10 '18 at 05:47