In our previous post we look into how the compiler organize our code into sections, now is time to see how we can assign those section in different addresses. We are going to require an extra step because dealing with memory addresses is a job for the Linker, let's write the following code:
unsigned long var1;
unsigned long var2 = 34;
int main( void )
{
return 0;
}
Compile and display the header information one more time
$ arm-none-eabi-gcc -c main.c -o main.o -mcpu=cortex-m0plus
$ arm-none-eabi-objdump -h main.o
main.o: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000c 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000004 00000000 00000000 00000040 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000004 00000000 00000000 00000044 2**2
ALLOC
3 .comment 0000001f 00000000 00000000 00000044 2**0
CONTENTS, READONLY
4 .ARM.attributes 0000002c 00000000 00000000 00000063 2**0
CONTENTS, READONLY
Nothing new. This time lets focus on column VMA ( virtual memory address ), for the moment we can observe all sections had been assigned a memory address of 0x00000000 which is not what we want because that’s mean all of them will be overlapped, we need somehow assign different addresses. We can do that easily with our friend Linker just like this
$ arm-none-eabi-gcc -c main.c -o main.o -mcpu=cortex-m0plus
$ arm-none-eabi-gcc main.o -o main.elf -nostdlib -e main -mcpu=cortex-m0plus -Ttext 0x1000 -Tbss 0x2000 -Tdata 0x3000
$ arm-none-eabi-objdump -h main.elf
main.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000c 00001000 00001000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00000004 00002000 00002000 0000100c 2**2
ALLOC
2 .data 00000004 00003000 00003000 00003000 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .persistent 00000000 00003004 00003004 00003004 2**0
CONTENTS, ALLOC, LOAD, DATA
4 .noinit 00000000 00002004 00002004 00000000 2**0
ALLOC
5 .comment 0000001e 00000000 00000000 00003004 2**0
CONTENTS, READONLY
6 .ARM.attributes 0000002c 00000000 00000000 00003022 2**0
CONTENTS, READONLY
On column VMA sections .text, .bss and .data we can observe addresses are now the ones we indicated at the moment we link our program using -Ttext, -Tbss and -Tdata options, The numbers I used are just for illustrative purpose but in theory you will assigned the address where the flash and RAM memories are located.
And what about the .rodata and the custom sections we create, how can we indicate where to place those section with the linker?. well you can not, at least not in this way, we need a different approach, something more sophisticated. We need a Linker script!!