We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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).