mikrocontroller.net

Forum: Compiler & IDEs Probleme mit ld und Vektortabelle


Autor: Ilu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(reset_handler)

SECTIONS
{
  .text 0x20012000 : { 
    _stext = .;
    *(.text)
    *(.rodata)
    *(.rodata*)
    . = ALIGN(4);
     _etext = . ;
  }

  .data 0x200000 : AT ( ADDR (.text) + SIZEOF (.text) ) { 
    _sdata = .;
    *(.vectors)
    *(.data)
    _edata = .;
  }

  .bss (NOLOAD) : { 
    . = ALIGN(4);
    _sbss = .;
    *(.bss)
    _ebss = .;
  }
}
end = .;

Mein erster Schritt was also das BSS an seiner Loadaddress (im externen
RAM) zu lassen.

Funktionierendes Linkerscript mit BSS im externen RAM
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(reset_handler)

SECTIONS
{
  .text 0x20012000 : { 
    _stext = .;
    *(.text)
    *(.rodata)
    *(.rodata*)
    . = ALIGN(4);
     _etext = . ;
  }

  .data 0x200000 : AT ( ADDR (.text) + SIZEOF (.text) ) { 
    _sdata = .;
    *(.vectors)
    *(.data)
    _edata = .;
  }

  .bss (LOADADDR(.data) + SIZEOF(.data)) (NOLOAD) : {
    . = ALIGN(4);
    _sbss = .;
    *(.bss)
    _ebss = .;
  }
}
end = .;
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
arm-elf-gcc -nostartfiles -Wl,-Map=debug.map,--cref -T elf32-littlearm.lds -n -o debug.elf crt0.o main.o init.o
arm-elf-objcopy --strip-debug --strip-unneeded --verbose debug.elf -O binary debug.bin
copy from `debug.elf' [elf32-littlearm] to `debug.bin' [binary]

Auszug aus dem MAP-File
                0x2001be3c                _etext = .

.vector         0x00200000       0x78 load address 0x2001be3c
                0x00200000                _sdata = .
 *(.vectors)
 .vectors       0x00200000       0x78 crt0.o
                0x00200078                _edata = .

.bss            0x2001beb4      0x110
                0x2001beb4                . = ALIGN (0x4)
                0x2001beb4                _sbss = .
 *(.bss)

Kaputtes Linkerscript
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(reset_handler)

SECTIONS
{
  .text 0x20012000 : { 
    _stext = .;
    *(.text)
    *(.rodata)
    *(.rodata*)
    . = ALIGN(4);
  }

  .data : AT ( ADDR (.text) + SIZEOF (.text) ) { 
    *(.data)
     _etext = . ;
  }

  .vector 0x200000 : AT ( ADDR (.data) + SIZEOF (.data) ) {
    _sdata = .;
    *(.vectors)
    _edata = .;
  }

  .bss (LOADADDR(.vector) + SIZEOF(.vector)) (NOLOAD) : {
    . = ALIGN(4);
    _sbss = .;
    *(.bss)
    _ebss = .;
  }
}
end = .;
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

Autor: Ilu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um mir mal selber zu helfen:
wenn man im crt0.S statt
.section .vectors

einfach
.section .vectors, "a", %progbits

schreibt, dann klappts auch mit dem linken...

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus Interesse, da ich mich selber gerade einarbeite:

Was macht
.section .vectors, "a", %progbits

bzw. was machen die zusätzlichen Parameter im Vergleich zu der Anweisung 
darüber?

Vielen Dank für eure Hilfe!

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max schrieb:
> bzw. was machen die zusätzlichen Parameter im Vergleich zu der Anweisung
> darüber?

Die setzen die Flags für ELF Sektionen, anderenfalls werden die 
Defaultwerte abhängig vom Sektornamen verwendet. Aus der GNU as 
Dokumentation:

|   If no flags are specified, the default flags depend upon the section
| name.  If the section name is not recognized, the default will be for
| the section to have none of the above flags: it will not be allocated
| in memory, nor writable, nor executable.  The section will contain data.

Und .vectors ist eben kein bekannter Standard-Sektionsname wie .text, 
.data und .bss.


Aber für ARM Vektortabellen würde ich "ax" einsetzen, schließlich 
bestehen die Einträge ausser bei ARMv7-M aus ausführbarem Code.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.