[U-Boot] linker question u-boot - setting armv8 mem_map struct at runtime

Matthias Brugger mbrugger at suse.com
Tue Oct 22 14:17:39 UTC 2019

Hi all,

I'm trying to support one binary that can boot from RPi3 and RPi4 [1].

For this I need to set mem_map at runtime [2].
Up to now, mem_map is defined in lowlevel_init.S which pushes it to section

But as Alex noted in the thread, much cleaner would be to define mem_map as an
external variable which is put into .data

So the logical solution would be something like
struct mm_region *mem_map = bcm283x_mem_map;
in arch/arm/mach-bcm283x/init.c
But that takes the value at compile time and does not update mem_map afterwards
mach_cpu_ini(). Which leads to a binary that can only boot on RPi3.

If instead I define:
struct mm_region __attribute__ ((section (".data"))) *mem_map;
Then U-boot updates the variable at run-time and boots as expected on RPi3 and RPi4.

I'm banging my head against this for the last few days, but don't really grok
why this happens. I suppose that it has something to do with the relocation of
U-Boot after boot_init_f sequence is finished, but I'm not sure.

The only difference I can see when using assignment at compile time is, that
mem_map get's put into .data.mem_map section [3] and in the relocation section
[4] we can see extra entries in section '.rela.text.mach_cpu_init', .data.mem_map
Apart from that a nwe section .rela.data.mem_map is created which holds one
entry .data.bcm283x_mem_map

To be honest I don't really understand what's going on and if just pushing
mem_map to .data through a GCC attribute is the correct thing to do or not.

Any help would be appreciated.


[2] https://patchwork.ozlabs.org/patch/1168355/
[3] objdump --disassemble-all arch/arm/mach-bcm283x/built-in.o
[4] readelf --relocs arch/arm/mach-bcm283x/built-in.o

More information about the U-Boot mailing list