Good question. I haven’t yet seen such a of this dynamic linking between two images. So you would e.g. build a bootloader the resulting .elf file would place a function abc()
at a pretty random address, e.g., 0x80000ab
, and on a application rebuild you would want a call to that function go directly to 0x80000ab
?
Forum posts like Share code between bootloader and application and Dynamic Linking of librairies without and OS suggest that creating a jump- or function table at a constant place in flash would be an option. The table would then contain the actual addresses of the functions with a convention that e.g. the first index would describe function f_1, etc.
In the ESP-IDF project for the ESP32 project I’ve also seen that the linker script just exposes addresses of functions, which are e.g. stored in its factory-programmed, unchangable mask-ROM, so that these calls can be resolved.
With a header declaration like e.g.
that can then be resolved.
With a little bit of an extra script, such linker script directives can also be surely generated by running the bootloader elf file through the toolchain-specific nm
tool to view the symbols and its addresses, then extract the addresses for the needed functions and generate the PROVIDE(func = addr);
text.
But that has also the significant drawback that an application would be linked against one specific bootloader version and the bootloader is not interchangable. If bootloader v1 placed function abc()
at one address and then app v1 was linked against that, as soon as another bootloader version would put the function at a different address while the app is kept the same, the app would crash, since it points to the old address. Same for the way if an app was linked with a newer bootloader but being placed in flash where an older bootloader is.
Thus the “jump table” approach would be prefferable I guess since an application would be invariant against internally changing addresses in the bootloader, as long as the correct address is always placed in the jump table of known constant address. Enforcing that an object like that jumptable is placed at a predictable address can also be done with the linker script in the bootloader I suppose. On modern operating systems, the PLT (procedure linkage table) and GOT (global offset table) (https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html) are a little fancier versions of a simple jump table, so one can have a look at how those work too.
There may also be a way where the bootloader is compiled to an .so
file that is dynamically linked against (without the bootloader code being placed in the application as result) with some link flags, I’m unsure how that would concretely work in this instance though.