Moin zusammen,
ich spiele momentan mit ein paar ARM Mikrocontrollern rum und bin dabei
über das Linker Script gestolpert. Die Aufgabe des Script's ist mir
durchaus klar und nach ein paar Seiten Dokumentation und Tutorials
verstehe ich soweit auch die grundlegende Syntax und Funktionsweise.
Womit ich aber aktuell sehr stark kämpfen muss ist die Auswahl der
Sektionen und den Zusammenhang mit einigen Code Teilen.
Ich nutze z.B. Yagarto von Michael Fischer. Tolle Toolchain funktioniert
alles soweit super und er hat auch ein paar Beispiele zur Verfügung
gestellt. Top. Aber woher bezieht der Herr seine Informationen für seine
Linker Script's?
Er verwendet z.B. eine .fastrun Sektion. Diese habe ich aber in keinen
anderen Beispiel gefunden (egal ob Code Sourcery oder andere). Das es
sich dabei um eine Sektion handelt, die für Code reserviert ist, der
danach aus dem RAM ausgeführt werden soll ist mir klar. Doch irgendwo im
Compiler muss ja festgelegt sein, dass der Compiler diese Sektionen
erstellt (für die einzelnen Objektdateien). Dazu kommt der Punkt, dass
der Compiler irgendwo her wissen muss, dass dieser Code vom RAM aus
ausgeführt werden soll.
Bisher habe ich dazu aber noch nichts gefunden.
Verlässt man die "einfache" Umgebung der Yagarto Beispiele wird es noch
viel schlimmer. Dort haben mich Sektionen wie glue_7, init,
vfp11_veneer, ARM.attributes und so weiter erwartet. Bei den Meisten
konnte ich bisher mittels Google zumindest eine Funktion heraus finden.
Aber z.B. die beiden letzten Erwähnten sind mir noch ein Rätsel.
Daher nun die wichtige Hauptfrage: Wie finde ich raus, welche Sektionen
es alles (für meine HW) geben kann und welche Funktionen haben die
einzelnen Sektionen dann?
Ich möchte am Ende in der Lage sein ein Linker Script zusammen zu
stellen, bei dem ich Bewusst die Sektionen ausgewählt habe und zumindest
darauf verweisen kann, was die Sektion macht.
Ich würde mich über eine Antwort sehr freuen (aber bitte keine Google
Antwort <- da habe ich schon mehr als 6 Stunden verbracht und wenn es da
zu finden ist suche ich definitiv nach dem Falschen).
MfG
Arne
Arne Maximilian R. schrieb:> Moin zusammen,>> ich spiele momentan mit ein paar ARM Mikrocontrollern rum und bin dabei> über das Linker Script gestolpert. Die Aufgabe des Script's ist mir> durchaus klar und nach ein paar Seiten Dokumentation und Tutorials> verstehe ich soweit auch die grundlegende Syntax und Funktionsweise.> Womit ich aber aktuell sehr stark kämpfen muss ist die Auswahl der> Sektionen und den Zusammenhang mit einigen Code Teilen.> Ich nutze z.B. Yagarto von Michael Fischer. Tolle Toolchain funktioniert> alles soweit super und er hat auch ein paar Beispiele zur Verfügung> gestellt. Top. Aber woher bezieht der Herr seine Informationen für seine> Linker Script's?> Er verwendet z.B. eine .fastrun Sektion. Diese habe ich aber in keinen> anderen Beispiel gefunden (egal ob Code Sourcery oder andere).
".fastrun" ist einfach nur ein Name einer input-section. Woanders hat
man vielleicht ramrun, runfromram oder ramfunc verwendet. Es gibt dafür
meines Wissens keine Vorgaben in Dokumenten von ARM. Das "fast" ist auch
nur dann schnell wenn die Ausführung aus dem RAM schnell ist, muss nicht
unbedingt bei allen Controllern der Fall sein.
> Das es> sich dabei um eine Sektion handelt, die für Code reserviert ist, der> danach aus dem RAM ausgeführt werden soll ist mir klar. Doch irgendwo im> Compiler muss ja festgelegt sein, dass der Compiler diese Sektionen> erstellt (für die einzelnen Objektdateien).
Binutils ld-Dokumentation gelesen? Unteschied zwischen input- und
output-sections verstanden? gcc-Dokumentation Abschnitte Attributes for
functions und for data gelesen?
Dem Compiler wird per Funktionsattribut im Quellcode mitgeteilt, das
diese Funktion einer input-section mit dem gewählten Namen zugeordnet
wird.
> Dazu kommt der Punkt, dass> der Compiler irgendwo her wissen muss, dass dieser Code vom RAM aus> ausgeführt werden soll.
Der Compiler "weiss" das auch nicht. Es ist Aufgabe des Linkers die
Adressen (LMA und VMA, siehe LD-Dokumentation) zuzuweisen. Am
Einfachsten ist es, eine input-section wie .ramrun/.fastrun in die
output-section .data mit aufzunehmen (siehe vorliegendes Linker-script).
Damit wird der Binärcode der Funktionen im Startup-Code mit allen
anderen Werten in .data (z.B. Initialwerte gloabler Variablen) von
ROM/Flash (LMA) ins RAM kopiert (VMA, vgl. vorliegenden startup-code).
> Bisher habe ich dazu aber noch nichts gefunden.
Im Speziellen mglw. nicht. Das Prinzip wurde aber wohl beim Studium der
Compiler- und Binutils-Dokumentation überlesen.
> Verlässt man die "einfache" Umgebung der Yagarto Beispiele wird es noch> viel schlimmer. Dort haben mich Sektionen wie glue_7, init,> vfp11_veneer, ARM.attributes und so weiter erwartet.
Wer erwartet? Die stehen vielleicht im Linker-Script und der Linker kann
somit Adressen zuweisen, wenn eine solche input-section nicht leer ist.
Einige input-sections können aber einfach leer sein.
> Bei den Meisten> konnte ich bisher mittels Google zumindest eine Funktion heraus finden.> Aber z.B. die beiden letzten Erwähnten sind mir noch ein Rätsel.
vfp11 bezieht sich auf Floating-Point. Wie z.B. bei den glue-Funktionen
erzeugt der Compiler intern Hilfsfunktionen in input-sections, die per
Linkerscript in output-sections aufgenommen werden.
> Daher nun die wichtige Hauptfrage: Wie finde ich raus, welche Sektionen> es alles (für meine HW) geben kann und welche Funktionen haben die> einzelnen Sektionen dann?
"Geben kann": den Linker mit Option --verbose aufrufen. Dann erscheint
das default linker-script, darin sollten alle mgl. input-sections
enthalten sein. Einige können durchaus leer sein (z.B. Interwork
glue-Funktionen bei Controllern, die kein Interwork unterstützen).
"Funktion": gcc-Dokumentation, binutils-Dokumentation, ARM Infocenter.
Ob dort dann alle möglichen Sections beschrieben sind, weiss ich nicht,
alle kenne ich auch nicht.
> Ich möchte am Ende in der Lage sein ein Linker Script zusammen zu> stellen, bei dem ich Bewusst die Sektionen ausgewählt habe und zumindest> darauf verweisen kann, was die Sektion macht.
Vorschlag Lernziel 1: Zusammenhang input- und output-sections, Map-Files
lesen lernen (ist nicht wild).
So sehr viel ist im 'üblichen' Geschäft nicht zu "wählen", .text, .data,
.bss input macht der Compiler schon. Spannend wird es eher bei quirligem
Speicherlayout (Bootloader, verschieden schnelle Speicher,
Speicherbereiche mit eingeschränkten Funktionen oder Sonderfunktionen,
Interruptvektoren in mehreren Ausführungen,...)
> Ich würde mich über eine Antwort sehr freuen (aber bitte keine Google> Antwort <- da habe ich schon mehr als 6 Stunden verbracht und wenn es da> zu finden ist suche ich definitiv nach dem Falschen).
Scheint so. Manchmal muss man halt erst durch viele Seiten
PDF/bilderlose html. Hier z.B. die GNU Bintuils Linkerdokumentation
("ld"): http://sourceware.org/binutils/docs/ld/ nicht nur überfliegen,
ist ein guter Anfang bezügl. Linker, Linkerscripts
Moin,
ich glaube du hast mein Anliegen und meine Fragen nicht ganz verstanden.
Martin Thomas schrieb:> ".fastrun" ist einfach nur ein Name einer input-section. Woanders hat> man vielleicht ramrun, runfromram oder ramfunc verwendet. Es gibt dafür> meines Wissens keine Vorgaben in Dokumenten von ARM. Das "fast" ist auch> nur dann schnell wenn die Ausführung aus dem RAM schnell ist, muss nicht> unbedingt bei allen Controllern der Fall sein.
Das die Input Sektion einen beliebigen Namen haben kann ist mir klar.
Ich kann auch eigene Input Sektionen definieren. Dies mache ich z.B. für
mein Interrupt Vector (.isr_vector heißt die Sektion bei mir).
Die Frage hier ist aber WOHER weiß der COMPILER, dass der Code nicht in
die .text (Input <- zumindest aus Linkersicht) Sektion kommt? Dies muss
der Compiler wissen, dass der Code in die .fastrun Sektion kommt? Woher
kann ich die Informationen ziehen, dass der Compiler diese Sektion, mit
diesem Namen und GENAU dieser Funktion erstellt?
Martin Thomas schrieb:> Binutils ld-Dokumentation gelesen? Unteschied zwischen input- und> output-sections verstanden? gcc-Dokumentation Abschnitte Attributes for> functions und for data gelesen?>> Dem Compiler wird per Funktionsattribut im Quellcode mitgeteilt, das> diese Funktion einer input-section mit dem gewählten Namen zugeordnet> wird.
Ja ich habe die Dokumentation gelesen. Dem Linker ist ja aber erst
einmal egal, welche Sektionen er vorgeworfen bekommt. Er nimmt ja die
Input Sektionen und ordnet sie seinen vorgesetzten Output Sektionen zu.
Also dieser Sachstand ist mir soweit klar.
Die GCC Dokumentation habe ich soweit überflogen bzw. versucht zu
durchsuchen. Ich konnte dort aber nicht die wichtigen Punkte finden. Es
werden zwar Sektionen erwähnt. Aber Sektionen wie z.B. die fastrun
Sektion tauchen nicht in der GCC Dokumentation unter dem Function
Attributes Abschnitt auf (siehe
http://gcc.gnu.org/onlinedocs/gcc-4.3.2//gcc/Function-Attributes.html ).
Das gewisse Funktionsattribute im Quellcode auftauchen können und nicht
unbedingt verwendet werden ist mir auch klar. Es gibt aber Sektionen die
ich nicht explizit angebe, die ich nicht gesondert angebe und die
wiederum auch nicht zu den Standardsektionen (wie BSS, Data und Text)
gehören.
Martin Thomas schrieb:> Der Compiler "weiss" das auch nicht. Es ist Aufgabe des Linkers die> Adressen (LMA und VMA, siehe LD-Dokumentation) zuzuweisen. Am> Einfachsten ist es, eine input-section wie .ramrun/.fastrun in die> output-section .data mit aufzunehmen (siehe vorliegendes Linker-script).> Damit wird der Binärcode der Funktionen im Startup-Code mit allen> anderen Werten in .data (z.B. Initialwerte gloabler Variablen) von> ROM/Flash (LMA) ins RAM kopiert (VMA, vgl. vorliegenden startup-code).
Ja ist mir klar aber irgendwoher muss die Sektion ja kommen.
Martin Thomas schrieb:> Wer erwartet? Die stehen vielleicht im Linker-Script und der Linker kann> somit Adressen zuweisen, wenn eine solche input-section nicht leer ist.> Einige input-sections können aber einfach leer sein.
"Die Sektionen haben mich dort erwartet." Ja mir ist auch klar, dass
nicht alle Sektionen belegt werden müssen. Z.B. die .jcr Sektion werde
ich kaum benötigen, da ich nicht mit Java rumspiele und mein Chip es
meines Wissens nach nicht unterstützt. Es ändert aber nichts daran, dass
es Sektionen geben kann, dass der Compiler mir Objekt Dateien vorwirft,
in denen Sektionen drin stecken, die ich unterstützen könnte aber nicht
tue.
Martin Thomas schrieb:> vfp11 bezieht sich auf Floating-Point. Wie z.B. bei den glue-Funktionen> erzeugt der Compiler intern Hilfsfunktionen in input-sections, die per> Linkerscript in output-sections aufgenommen werden.
Das mit dem vfp11 habe ich auch rausgefunden. Nicht schwer. Was macht
aber die Sektion und in welchem Zusammenhang kann diese auftauchen?
Die glue Sektion ist hingegen schon klar. Diese Sektion kombiniert ARM
und Thumb Code. Da ich mit Cortex-Mx Mikrocontrollern arbeite benötige
ich diese Sektionen zwar nicht aber sie scheinen überall als Legacy
Produkteingebunden zu sein.
Aber hier wieder die Frage: Aus welcher Dokumentation ziehe ich die
Informationen für die Sektionen offiziell (und nicht aus einem Forum)?
Martin Thomas schrieb:> "Geben kann": den Linker mit Option --verbose aufrufen. Dann erscheint> das default linker-script, darin sollten alle mgl. input-sections> enthalten sein. Einige können durchaus leer sein (z.B. Interwork> glue-Funktionen bei Controllern, die kein Interwork unterstützen).> "Funktion": gcc-Dokumentation, binutils-Dokumentation, ARM Infocenter.> Ob dort dann alle möglichen Sections beschrieben sind, weiss ich nicht,> alle kenne ich auch nicht.
Diese Information hat mir tatsächlich ein bisschen geholfen. Das default
Skript scheint zumindest die Sektionen aufzulisten. Danke, dass hat mir
zumindest eine genauere Übersicht geliefert.
Martin Thomas schrieb:> Vorschlag Lernziel 1: Zusammenhang input- und output-sections, Map-Files> lesen lernen (ist nicht wild).
Done, done und done (leider schon vorher).
Ich möchte mich schon einmal entschuldigen, wenn ich etwas unhöflich
und/oder undankbar rüber kam. Ich bin durch das Thema nur langsam etwas
verzweifelt. Ich bin dir auf jeden Fall schon einmal für die Hilfe
dankbar!
Ich weiß auch nicht, ob ich einen imaginären Heiligen Gral suche, den es
nicht gibt. Doch ich versuche halt tatsächlich nur eine dokumentierte
(offizielle) Dokumentation zu finden, in der die Sektionen alle
auftauchen (und beschrieben werden). Dabei will ich aber nicht aus
mehreren Linker Script's die Sachen für mein System zusammen schneiden,
sondern halt bewusst die Sektionen auswählen und auch aufschreiben. Oder
such ich hier tatsächlich etwas nicht existierendes?
MfG
Arne
Arne Maximilian R. schrieb:> Ich kann auch eigene Input Sektionen definieren. Dies mache ich z.B. für> mein Interrupt Vector (.isr_vector heißt die Sektion bei mir).
Offensichtlich machst Du das nicht komplett, denn ...
Arne Maximilian R. schrieb:> Die Frage hier ist aber WOHER weiß der COMPILER, dass der Code nicht in> die .text (Input <- zumindest aus Linkersicht) Sektion kommt?
... dann hast Du im Quelltext kein __attribute__ stehen, in welchem
die Sektion angegeben wird, wenn man nicht die Standardsektion haben
will:
Arne Maximilian R. schrieb:> Ich möchte mich schon einmal entschuldigen, wenn ich etwas unhöflich> und/oder undankbar rüber kam.
Ich fand es etwas undankbar.
Arne Maximilian R. schrieb:> Ich weiß auch nicht, ob ich einen imaginären Heiligen Gral suche, den es> nicht gibt.
Die Verständnis von Linker-Skripten ist m. E. eine längere Suche wert,
wenn man nicht nur mit AVRs zu tun hat. Bei AVR kommt man damit nicht in
Berührung, mit ARMs habe ich begonnen, und es hat für MSP430, PIC32 und
Renesas RX sehr geholfen (solange man nur mit GCC unterwegs ist).
> Doch ich versuche halt tatsächlich nur eine dokumentierte> (offizielle) Dokumentation zu finden, in der die Sektionen alle> auftauchen (und beschrieben werden).
Die "eine" gibt es nicht, da es diese nicht geben kann.
> Dabei will ich aber nicht aus> mehreren Linker Script's die Sachen für mein System zusammen schneiden,> sondern halt bewusst die Sektionen auswählen und auch aufschreiben. Oder> such ich hier tatsächlich etwas nicht existierendes?
Doch :-). Genau das erste wirst Du tun, und mit dem zweiten kombinieren.
M. E. hast Du eine falsche Erwartungshaltung. Es gibt kein "Linker
scripts for Dummies in 21 days". Das Verständnis von Linker-Skripten ist
ein längerer Prozess, bei dem im Laufe der Jahre immer wieder neue
Wissensschnipsel hinzukommen, z. B. für "Run in RAM", FPU, uint64_t etc.
Moin,
danke schonmal für die Antwort. Ja das bei dem ersten war etwas daneben.
Ich möchte mich da noch einmal bei Martin Thomas entschuldigen.
Roland H. schrieb:> M. E. hast Du eine falsche Erwartungshaltung. Es gibt kein "Linker> scripts for Dummies in 21 days". Das Verständnis von Linker-Skripten ist> ein längerer Prozess, bei dem im Laufe der Jahre immer wieder neue> Wissensschnipsel hinzukommen, z. B. für "Run in RAM", FPU, uint64_t etc.
Der grundsätzliche Aufbau der Skripte schien mir nicht ganz so
kompliziert, doch die Auswahl der passenden Sektionen befriedigt mich
halt noch nicht.
Aber verstehe ich dich jetzt richtig, dass sich die Auswahl der
Sektionen nach und nach entwickelt? Sprich je nachdem über was ich im
Laufe der Zeit stolpere muss ich mein Skript aktualisieren?
Und ich werde auch kein Dokument finden, in dem alle Sektionen
aufgelistet sind, die der GCC für ein ARM Kern anlegen kann (C und C++)?
MfG
Arne
Arne Maximilian R. schrieb:> Aber verstehe ich dich jetzt richtig, dass sich die Auswahl der> Sektionen nach und nach entwickelt? Sprich je nachdem über was ich im> Laufe der Zeit stolpere muss ich mein Skript aktualisieren?
Ja und Ja. Im Zweifel lasse ich allerdings Sektionen drin, und
aktualisiere den Kommentar, wenn sich das Wissen gemehrt hat ;-)
Das Problem beim Weglassen besteht darin, dass es zunächst funktionieren
kann. Plötzlich geht es aber nicht mehr, wenn man z. B. ein
"überflüssiges" ALIGN entfernt hat.
> Und ich werde auch kein Dokument finden, in dem alle Sektionen> aufgelistet sind, die der GCC für ein ARM Kern anlegen kann (C und C++)?
Vielleicht im ARM Infocenter.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0474c/BABEHEDA.html
Da gibt es auch ein "default GNU ld linker script used by armlink".
Dort stehen allerdings die µC-spezifischen Bereiche (z. B. normales RAM
und CCM-RAM beim stm32f4) nicht drin.
Ok danke. Es ist zwar nicht die traumhaften Informationen. Aber wie du
schon beschrieben hast ist es halt ein dauerhafter Lernprozess.
Zumindest weiß ich jetzt, wie ich vorgehen muss. Danke.
MfG
Arne