Hallo,
ich bin Neuling was Mikrocontroller angeht und verzweifel hier gerade an
meinem ersten Linkescript fuer ein ARM Board.
Umgebung:
- Atmel 91sam9260
- Yagarto tools unter Windows
- Telit GE863-PRO3 eval board
Problem:
Das Board hat 8MB prozessorexternen RAM (0x2000.0000 - 0x207F.FFFF).
Meine Anwendung wird vom U-BOOT aus dem FLASH an die Adresse 0x2001.2000
geladen und soll dort auch ausgefuehrt werden.
Wenn ich das richtig verstehe, dann muss die Vectortabelle fuer den ARM
in die 4kB prozessorinternen RAM (0x20.0000 - 0x20.1000).
Der Startupcode von meiner Anwendung soll also die paar Byte aus der
Anwendung in den internen RAM kopieren (alles zwischen _sdata und
_edata) und alles ist gut...
Das Problem ist nur leider, dass das mitgelieferte Beispielscript vom
Hersteller die Vektoren, das Datensegment und das BSS in den internen
RAM klatscht. Das geht nur so lange gut, wie das alles <4k ist. :)
Original Script
1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
2 | OUTPUT_ARCH(arm)
|
3 | ENTRY(reset_handler)
|
4 |
|
5 | SECTIONS
|
6 | {
|
7 | .text 0x20012000 : {
|
8 | _stext = .;
|
9 | *(.text)
|
10 | *(.rodata)
|
11 | *(.rodata*)
|
12 | . = ALIGN(4);
|
13 | _etext = . ;
|
14 | }
|
15 |
|
16 | .data 0x200000 : AT ( ADDR (.text) + SIZEOF (.text) ) {
|
17 | _sdata = .;
|
18 | *(.vectors)
|
19 | *(.data)
|
20 | _edata = .;
|
21 | }
|
22 |
|
23 | .bss (NOLOAD) : {
|
24 | . = ALIGN(4);
|
25 | _sbss = .;
|
26 | *(.bss)
|
27 | _ebss = .;
|
28 | }
|
29 | }
|
30 | end = .;
|
Mein erster Schritt was also das BSS an seiner Loadaddress (im externen
RAM) zu lassen.
Funktionierendes Linkerscript mit BSS im externen RAM
1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
2 | OUTPUT_ARCH(arm)
|
3 | ENTRY(reset_handler)
|
4 |
|
5 | SECTIONS
|
6 | {
|
7 | .text 0x20012000 : {
|
8 | _stext = .;
|
9 | *(.text)
|
10 | *(.rodata)
|
11 | *(.rodata*)
|
12 | . = ALIGN(4);
|
13 | _etext = . ;
|
14 | }
|
15 |
|
16 | .data 0x200000 : AT ( ADDR (.text) + SIZEOF (.text) ) {
|
17 | _sdata = .;
|
18 | *(.vectors)
|
19 | *(.data)
|
20 | _edata = .;
|
21 | }
|
22 |
|
23 | .bss (LOADADDR(.data) + SIZEOF(.data)) (NOLOAD) : {
|
24 | . = ALIGN(4);
|
25 | _sbss = .;
|
26 | *(.bss)
|
27 | _ebss = .;
|
28 | }
|
29 | }
|
30 | end = .;
|
31 | PROVIDE(end = .);
|
Danach hab ich versucht Datensegment und Vektoren zu trennen. Das
folgende Linkerscript soll das bewirken (und meine laienhafte
Interpretation vom erzeugten MAP-File sagt mir auch, das es das tut),
aber die erzeugte Datei ist genau 120 Byte kleiner als mit dem anderen
Script (und das ist auch zufaelligerweise die Groesse des Vektorcodes
aus crt0.S).
Linkerlauf mit objdump
1 | arm-elf-gcc -nostartfiles -Wl,-Map=debug.map,--cref -T elf32-littlearm.lds -n -o debug.elf crt0.o main.o init.o
|
2 | arm-elf-objcopy --strip-debug --strip-unneeded --verbose debug.elf -O binary debug.bin
|
3 | copy from `debug.elf' [elf32-littlearm] to `debug.bin' [binary]
|
Auszug aus dem MAP-File
1 | 0x2001be3c _etext = .
|
2 |
|
3 | .vector 0x00200000 0x78 load address 0x2001be3c
|
4 | 0x00200000 _sdata = .
|
5 | *(.vectors)
|
6 | .vectors 0x00200000 0x78 crt0.o
|
7 | 0x00200078 _edata = .
|
8 |
|
9 | .bss 0x2001beb4 0x110
|
10 | 0x2001beb4 . = ALIGN (0x4)
|
11 | 0x2001beb4 _sbss = .
|
12 | *(.bss)
|
Kaputtes Linkerscript
1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
2 | OUTPUT_ARCH(arm)
|
3 | ENTRY(reset_handler)
|
4 |
|
5 | SECTIONS
|
6 | {
|
7 | .text 0x20012000 : {
|
8 | _stext = .;
|
9 | *(.text)
|
10 | *(.rodata)
|
11 | *(.rodata*)
|
12 | . = ALIGN(4);
|
13 | }
|
14 |
|
15 | .data : AT ( ADDR (.text) + SIZEOF (.text) ) {
|
16 | *(.data)
|
17 | _etext = . ;
|
18 | }
|
19 |
|
20 | .vector 0x200000 : AT ( ADDR (.data) + SIZEOF (.data) ) {
|
21 | _sdata = .;
|
22 | *(.vectors)
|
23 | _edata = .;
|
24 | }
|
25 |
|
26 | .bss (LOADADDR(.vector) + SIZEOF(.vector)) (NOLOAD) : {
|
27 | . = ALIGN(4);
|
28 | _sbss = .;
|
29 | *(.bss)
|
30 | _ebss = .;
|
31 | }
|
32 | }
|
33 | end = .;
|
34 | PROVIDE(end = .);
|
Es waere wunderbar wenn mir jemand den Knoten im Kopf aufloesen koennte,
ich hab naemlich langsam keine Idee mehr.
Beispielscripte die ich beim googlen gefunden habe waren immer extrem
kompliziert, ich gebe mich ja noch der Illusion hin, das mein Problem
eigentlich ganz einfach ist :)
Danke und Gruss
Ilu