Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically load code on embedded target

Tags:

gcc

embedded

ld

I have an application which runs on bare metal target and has the following structure

  • main.c
  • service.c/.h

It's compiled to ELF executable (system.elf) using standard gcc -c, ld sequence. I use linker to generate a map file showing adresses of all symbols.

Now, without re-flashing my system I need to add an extra functionality with a custom run-time loader. Remember, this is a bare-metal with no OS.

I'd like to

  • compile extra.c which uses APIs defined in service.h (and somehow link against existing service.o/system.elf)
  • copy the resulting executable to my SDRAM at runtime and jump to it
  • loaded code should be able to run and accesses the exported symbols from service.c as expected

I thought I'd be able to to reuse map file to link the extra.o against system.elf but this didn't work:

ld -o extraExe extra.o system.map

Does gcc or ld have some mode to make this late linking procedure? If not, how can I achieve dynamic code loading which I outlined above?

like image 640
Tarek Eldeeb Avatar asked Jun 19 '17 13:06

Tarek Eldeeb


1 Answers

You can use the '-R filename' or '--just-symbols=filename' command options in ld. It reads symbol names and their addresses from filename, but does not relocate it or include it in the output. This allows your output file to refer symbolically to absolute locations of memory defined in your system.elf program. (refer to ftp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html).

So here filename will be 'system.elf'. You can compile extra.c with GCC normally including services.h but without linking and generate 'extra.o' then call ld as below:

ld -R"system.elf" -o"extra.out" extra.o

The 'extra.out' shall have your symbols linked. You can use objdump to compare contents of both 'extra.out' and 'extra.o'. Note that you can always pass the start address of your program to the ld (e.g. -defsym _TEXT_START_ADDR=0xAAAA0123) as well as start address of other memory sections like bss,data. (i.e. -Tbss, -Tdata)
Be careful to use a valid address that does not conflict with your 'system.elf' as ld will not generate error for that. You can define new areas for the loaded code+data+bss in your original linker script and re-compile the system.elf then point the start addresses to your defined areas while linking 'extra.o'.

like image 90
Andrew SADEK Avatar answered Oct 23 '22 22:10

Andrew SADEK