www.mikrocontroller.net

Forum: Compiler & IDEs Fragen zu ld und Linker-Scripts (fill, defsym,.)


Autor: Siddhartha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

ich kämpfe gerade bissl mit dem arm-elf-ld rum und krieg das 
Linker-Script einfach nicht so hin, wie ich gerne will.

Grundsätzlich geht es darum, dass ich meinen Code (für einen 
AT91SAM7S256) so kompilieren/linken will, dass das daraus entstehende 
Binary immer die gleiche Grösse hat, nämlich die Grösse vom internen 
Flash (256 kB). Zudem sollen die letzten Bytes mit dem CRC16-Wert der 
restlichen Bytes gefüllt werden. Die Berechnung des CRC16 wird dabei mit 
einem kleinen Konsolen-Tool gemacht. Nun habe ich dabei aber mehrere 
Probleme, die ich entweder nicht richtig verstehe oder mich einfach noch 
zu wenig mit Linker-Scripts auskenne :-(

Also zuerst einmal wollte ich das mit dem CRC-Wert so machen:
  - Alles kompilieren, linken und mit objcopy ein Binary erstellen 
(dabei werden die Bytes, die für den CRC16 gebraucht werden, mit 0 
gefüllt)
  - CRC16-Tool laufen lassen und so den CRC Wert bestimmen
  - Linker-Script nochmals anwerfen und über --defsym CRC16=0xXXXX den 
berechneten Wert übergeben und vom Linker-Script ganz am Ende einfügen 
lassen.

Der relevante Teil meines Linker-Scripts sieht deshalb folgendermassen 
aus:
__CRC_START__  = 0x03FFFE;
PROVIDE(CRC16 = 0x0000);

crc : AT ( __CRC_START__ )
{
    SHORT(CRC16);
}

Aber irgendwie wird immer 0x0000 eingefügt und nicht der berechnete 
CRC16-Wert. Wenn ich mir im Map-File den "Speicher-Aufbau" anschaue, 
erscheint ganz am schluss (nach der crc-section) ein Eintrag zur Adresse 
mit dem Wert des berechneten CRC16-Werts mit dem entsprechenden Wert.
Was mache ich dabei falsch? Oder ist --defsym dafür gar nicht geeignet?

Mein zweites Problem ist, dass ich alles, was nicht mit Code oder 
nutzbaren Daten gefüllt ist, mit 0xFFFFFFFF (was ja der Grundzustand 
eines Flash-Speichers ist) füllen will, damit es da keine Probleme mit 
der CRC-Überprüfung gibt. Dafür gibt es ja das FILL-Kommando oder die 
=fillexp-Angabe bei Sections.
Komischerweise ist es jetzt jedoch so, dass im erstellten Binary zwar an 
den entsprechenden Stellen der korrekte Füllwert steht (wobei .data und 
.bss sections mit 0 und nicht mit 1 gefüllt werden wegen RAM). Wenn ich 
das Binary dann aber über JTAG ins interne Flash des AT91SAM7S256 lade, 
dann steht an den Adressen, wo die .data und .bss sections sind, überall 
1 und nicht 0 und an den Stellen, die ich extra manuell mit 1 gefüllt 
habe, steht teilweise irgendwelcher Code.
Habe ich in dem Vorgehen irgendeinen Denkfehler? Warum wird das Binary 
nicht genau so ins interne Flash geschrieben, wie ich es erstellt habe?

Danke für eure Hilfe!

PS: Ich weiss dass es bissl viel auf einmal ist, sorry.

Autor: Siddhartha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So konnte beide Probleme lösen.

Das defsym-Problem hat sich damit gelöst, dass ich einfach die Zeile
PROVIDE(CRC16 = 0x0000);
weggelassen habe und beim ersten Linker-Aufruf per defsym einfach 0x0000 
übergeben habe und beim zweiten Mal den richtigen CRC16 Wert.

Das andere Problem habe ich mit objcopy und dessen Parameter --gap-fill 
gelöst, das schön alle "Löcher" mit dem angegebenen Wert füllt.

Autor: Sascha M. (siddhartha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich bin es doch nochmals, weil ich doch nochmal auf ein Problem 
gestossen bin.

Bisher hat alles gut funktioniert, aber da das Programm unterdessen doch 
schon wieder beachtlich gewachsen ist, hat sich folgendes Problem 
ergeben:

Im Linker-Script werden die Sections in folgender Reihenfolge definiert:

.text
.data
.bss
.crc

Wobei .crc genau 2 Byte vor Flash-Ende (256kB) stehen muss.
Unterdessen ist die .bss Section jedoch so gross geworden, dass die 
ersten drei Sections zusammen grösser sind als 256kB. Da der Linker 
nicht fähig ist, den Location Counter (gibt die momentane Adresse an) zu 
dekrementieren und die .bss Section über die Adresse der .crc Section 
hinaus geht, bricht der Linker natürlich mit einem Section Overlapping 
Error ab.
Das ist meiner Meinung nach theoretisch auch logisch und korrekt, ABER 
schlussendlich steht doch die .bss Section gar nicht im BIN File drin, 
das vom Linker generiert wird. Die wird im Linker-Script ja nur benötigt 
um die Grösse der Section zu ermitteln, damit der Startup Code das dann 
im RAM belegen kann oder nicht?

Basierend auf dieser Überlegung habe ich ausprobiert, was passiert, wenn 
ich die .bss Section hinter die .crc Section lege, sprich eigentlich 
ausserhalb des physikalisch verfügbaren Speicherbereichs. Wenn ich das 
so versuche, motzt der Linker zwar nicht mehr, aber das Programm läuft 
nicht und springt immer wieder zum Startup Code (ich nehme mal an, 
sobald er auf eine Variable, die in .bss stehen würde, trifft).

Hat jemand ne Idee, wie man dieses Phänomen umgehen könnte?
Oder habe ich irgendeinen Denkfehler gemacht?

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.