> Now I'm asking myself, what the output (ELF) does look like
The GNU tools offer some tools to "look" into the elf-file. I'm usually
just using the disassembly to verify things. It can be generated with
objdump (make calls objdump to generated it as *.lss when using my
"WinARM makefile template).
> - is the startup code really executed first
First of all the Controller looks for the reset-address and "jumps"
(sets PC) to this address. Since you are using a Cortex-M3 the
reset-address is expected at Address 0x00000004 (after the initial stack
pointer address at 0x00000000). It's not important where the
startup-code is located as long as it starts at the address given at
0x04.
>and especially WHY ?
Because it's address of the startup is given.
> Maybe I could get it working by trial and error but I would really be
> interested how it actually works.
"The prove of the pudding is the eating." (Samba Documentation)
> Can you tell me or do you know
> ressources regarding this issue?
gcc Manual, binutils/ld Manual, Cortex M3 Technical
Reference/Programming Guide
> -- -- -- --
>
> Further information: I'm comparing two ld-scripts, the first one seems
> to ignore startup related stuff and the second one includes it manually:
Why do you think "startup related stuff" is ignored?
> First:
> --
>
1 | > .text :
|
2 | > {
|
3 | > . = ALIGN(0x80); /* PM0056, Rev.1 (4/2009), 4.3.3 */
|
4 | > _isr_vectorsflash_offs = . - 0x08000000;
|
5 | > KEEP(*(.isr_vectorsflash))
|
6 | > . = ALIGN(4);
|
7 | > *(.text) /* code */
|
8 | > *(.text.*) /* remaining code
|
9 | > (-ffunction-sections)*/
|
10 | > *(.stub .gnu.linkonce.t.*)
|
11 | > *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data
|
12 | > (constants) */
|
13 | > *(.glue_7 .glue_7t) /* redundant for thumb2 ?! */
|
14 | > . = ALIGN(4);
|
15 | > _etext = .;
|
16 | > /* This is used by the startup in order to initialize the .data
|
17 | > secion */
|
18 | > _sidata = _etext;
|
19 | > } >FLASH
|
20 | >
|
I know this script from somewhere...
As you can see the all important input section with the reset-vector
(.isr_vectorsflash) is located first in the FLASH output-section. Since
the exceptions table is the only element in the input-section and the
reset-handler's address is the 2nd Element in the table the controller
finds the pointer to the startup-code. In this case the startup-code is
just treated as any other code (.text) since it's not important where it
is located.
> Second:
> --
>
1 | > .text :
|
2 | > {
|
3 | > KEEP(*(vector vector.*))
|
4 | > __startup_code__ = .;
|
5 | > $(TargetDir)startup.o (.text) /* Startup code */
|
6 | > __startup_code_end__ = .;
|
7 | > *(.text .text.*)
|
8 | > *(.gnu.linkonce.t.*)
|
9 | > *(.glue_7)
|
10 | > *(.glue_7t)
|
11 | > *(.gcc_except_table)
|
12 | > . = ALIGN(4);
|
13 | > *(.rodata .rodata*)
|
14 | > *(.gnu.linkonce.r.*)
|
15 | > . = ALIGN(4);
|
16 | > _etext = .;
|
17 | > } > FLASH
|
18 | >
|
Here the input-section with the vector-table is named vector instead of
.isr_vectorsflash in the previous example but the concept is the same:
The Reset-Hander Address in the vector still hast to point the the
startup machine-code. The only "real" difference I see is, that the
.text input-section in the object file startup.o are explicitly placed
right after the vector-table in memory (see binutils/ld manual). The
remaining code in the .text input-section(s) follows. I can't tell why
this approach has been chosen without looking into the reset of the
code.