The question concerns the vma and lma that can be expressed in the linker script with the keyword AT.
vma
lma
AT
let’s take the following linker script:
/* Entry Point */ ENTRY(main) /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K } /* Define output sections */ SECTIONS { /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); *(.data*) /* .data* sections */ . = ALIGN(4); } >RAM AT> FLASH /* Uninitialized data section */ .bss : { . = ALIGN(4); *(.bss*) *(COMMON) . = ALIGN(4); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } }
I’d like you to put the attention on the .data and .bss sections:
.data
.bss
.data : { . = ALIGN(4); *(.data*) /* .data* sections */ . = ALIGN(4); } >RAM AT> FLASH /* Uninitialized data section */ .bss : { . = ALIGN(4); *(.bss*) *(COMMON) . = ALIGN(4); } >RAM
I try to explain it in words: we are saying that .data has vma in RAM but lma in FLASH, instead .bss I expect it to have vma and lma identical and in RAM.
this is explained in 3.1 Basic Linker Script Concepts and in 3.6.8.2 Output Section LMA
I consider a very simple source file:
static int g_my_global_bss; static int g_my_global_data = 37; const int g_my_global_rodata = 45; int main(void) { g_my_global_bss = g_my_global_data + g_my_global_rodata; return 0; }
I build the elf with this makefile:
all: main.elf CFLAGS = \ -std=gnu11 \ -mcpu=cortex-m4 \ -mthumb \ -specs=nano.specs \ -O0 \ -Wall \ -ffunction-sections \ -fdata-sections \ -c \ -Werror LDFLGS = \ -mcpu=cortex-m4 \ -mthumb \ -specs=nano.specs \ -Wl,--gc-sections \ -Wl,--print-memory-usage LD_SCRIPT = STM32F410RBTx_FLASH.ld CC = arm-none-eabi-gcc main.elf: main.o $(CC) $(LDFLGS) -T$(LD_SCRIPT) -Wl,--cref,-Map=$(@:.elf=.map) -o $@ $^ main.o: main.c $(CC) $(CFLAGS) -o $@ $< .PHONY: clean clean: rm *.o *.elf *.map
linker tells me:
Memory region Used Size Region Size %age Used FLASH: 64 B 128 KB 0.05% RAM: 8 B 32 KB 0.02%
and size tells me:
size
max@jarvis:~/Dropbox/test_mem$ arm-none-eabi-size -G main.elf text data bss total filename 60 4 4 68 main.elf
then I extract the information of vma and lma from the elf using objdump.
objdump
max@jarvis:~/Dropbox/test_mem$ arm-none-eabi-objdump -h main.elf main.elf: file format elf32-littlearm Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000003c 08000000 08000000 00010000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .rodata 00000000 0800003c 0800003c 00020004 2**0 CONTENTS, ALLOC, LOAD, DATA 2 .data 00000004 20000000 0800003c 00020000 2**2 CONTENTS, ALLOC, LOAD, DATA 3 .bss 00000004 20000004 08000040 00020004 2**2 ALLOC 4 .ARM.attributes 0000002a 00000000 00000000 00020004 2**0 CONTENTS, READONLY 5 .comment 00000079 00000000 00000000 0002002e 2**0 CONTENTS, READONLY
again I highlight .data and .bss (and also .text for comparison)
.text
Idx Name Size VMA LMA File off Algn 0 .text 0000003c 08000000 08000000 00010000 2**2 2 .data 00000004 20000000 0800003c 00020000 2**2 3 .bss 00000004 20000004 08000040 00020004 2**2
why this unexpected behavior? What am I missing?
Is this a bug?
best regards Max
mastupristi said:3.6.8.2 Output Section LMA
mastupristi said:What am I missing?
The 3rd bullet point in that article.
The .bss section isn't loadable anyways, but if one insists on vma==lma, add AT(ADDR(.bss)). (Or remove '>RAM' to trigger the 5th bullet point).