linkerarmelffirmwarecortex-a8

ELF loading when VMA != LMA



I have a problem on this one. I am using ARM Cortex-A9 with DS-5 to create baremetal firmware. I modified my linker file to intentionally put the .data section LMA adjacent to the text and rodata sections, because its default run-time VMA is located 1MB away and the .bin image is around 1MB but containing 90% zeroes. And so I intentionally made LMA != VMA to save space. I also added a code in start.S that relocates the .data section from its lma to vma.

However on loading the resulting elf file in DS-5, it already loads all section to their VMA. As a result, my start.S code that is supposed to relocate data, copied from the LMA with garbage content to the already correct VMA, and soon afterwards those garbage resulted to fault.

I've had experience with unequal VMA and LMA in binary in Cortex-M4 and used gdb for its elf debugging, and there were no problems there, but it was microcontroller. In my current arm processor application, how would I then simulate in elf debugging the scenario of correctly copying data from its LMA to VMA. Most likely when booting standalone using the binary format there will be no problems, but right now we're still in elf debugging so I have to fix this.


Solution

  • Problem solved... I'd like to share the solution given to me:

    It helps to realize that "VMA" and "LMA" are GNU utility terminology and not in the ELF specification. Once you get down to looking at it from interpreting an ELF executable file, you will find that there is a program header field called "p_paddr" and another called "p_vaddr" - that makes it easier to search for! The option you need in DS-5 to use p_paddr is:

    ARM DS-5 Debugger Command Reference : 1.3.138 set elf load-segments-at-p_paddr

    By default, DS-5 uses p_vaddr, which is the standard. Usage of p_paddr is a quality of implementation, and is left very loosely defined in the specification. The ARM Compiler, Linker and C Library doesn't generate this information since the relocation process is handled internally (scatter loading). Some environments use p_paddr not as a physical address, but the load address (hence "LMA"), and some use it as an address to resolve symbols before and after MMU is enabled..