Forum: Mikrocontroller und Digitale Elektronik Low-Level-Initialisierung des GCC unterdrücken


von M. H. (doktorgnadenlos)


Lesenswert?

Hallo,

ich programmiere derzeit an Flashfunktionen für ein Freescale-Derivat 
aus der HCS12-Küche. Als Compiler und Linker dient der Compiler von 
GNU-GCC. Aufgerufen wird der Compiler/Linker über eine Kommandozeile.

Mein momentanes Problem : Der Linker schraubt vor meinen C-Code stets 
eine Low-Level-Initialisierung dazu, bei der insbesondere der Stack 
initialisiert wird und das RAM mit 0x00 initialisiert wird. Das ist für 
ANSI-C völlig in Ordnung, wenn ich meinen Code aber mit einer eigenen 
Vorinitialisierung ablaufen lassen will, funktioniert das nicht mehr. 
Mein momentaner Workaround ist ein Sprungbefehl an die Stelle, wo mein 
Code beginnt. Schöner und ökonomischer wäre es aber, wenn die 
Low-Level-Initialisierung ganz rausgenommen werden könnte.

Weiß jemand wie das funktioniert ? Gibt es dazu entsprechende 
Aufrufparameter ?

Danke für Eure Unterstützung.

von Thorsten (Gast)


Lesenswert?

Hallo,

es gibt 1001 Beispiele.

http://www.embedded.com/columns/technicalinsights/200900043?_requestid=207777
(weitere Artikel der Serie sind auch sehr spannend.)
Beim gcc ist es für alle Architekturen ähnlich.

Wichtig zu wissen ist, dass die gcc Toolchain aus verschiedenen 
Bauteilen (compiler, assembler, linker) besteht, die aber alle über das 
gleiche Frontend (z.B. ...-g++ oder ...-gcc aufgerufen werden. Wenn man 
c++ verwendet hat, sollte man zum linken auch g++ verwenden.

Während des compilierens werden die Objekt Dateien erzeugt. Diese werden 
dann entweder direkt oder über den Umweg von Bibliotheken (statische 
Bibliotheken sind nichts weiter als Archive von o-Dateien) dem Linker 
übergeben.

Der Linker legt dann  anhand des Linker-Scripts (LD-File)  die einzelnen 
Objekte im Speicher ab. Wenn Du als Entry point hier nicht den 
Eintrittspunkt angibst, den die Standardbibliotheken (standard 
Initialisierung) implementiert, dann wird statt dessen Dein Code 
verwendet.

Alternativ kannst Du auch das Symbol der Standard Bibliothek 
implementieren und statt dessen dem Linker die Anweisung geben zuerst in 
Deinem Code nach diesem Symbol zu suchen oder auch dem Linker sagen er 
soll überhaupt keine Standard Bibliothek verwenden.

Die erste Lösung hat aber den Vorteil, dass Du die anderen Funktionen 
der Standardbibliothek trotzdem noch nutzen kannst, z.B. 
Rechenoperationen, die Dein Prozessor nicht kann oder einige 
Initialisierungen, die für C++ wichtig sind, können später trotzdem noch 
explizit benutzt werden, nachdem der Prozessor z.B. schon auf den 
schnellen Takt umgeschaltet hat,

Für meinen arm-elf gcc sieht meine Linker-Zeile z.B. so aus:
arm-elf-g++ -mthumb startup.o <ganz viele o-Dateien> -mcpu=arm7tdmi 
-Tmain.ld 
-Wl,--cref,--gc-sections,-Map=main.map,--cref,--no-warn-mismatch   -lm 
--use-blx -mthumb-interwork   -o main.elf

Und im ld-File steht
...
ENTRY(_boot)
...

_boot ist Ein symbol, das in der Datei statup.o enthalten ist.
dann geht es irgendwann mit:


SECTIONS {

    .reset : {
        KEEP( *startup.o (.text) )
        . = ALIGN(0x4);
     } >ROM


weiter, das sorgt dafür, das alles was in der Section .text in startup.o 
File enthalten ist genau so als erstes im Speicher landet.


Und im startup.s file steht:
...
    .text
    .code 32

    .global _boot
    .func   _boot

_boot:

    B       _reset
...



Grüße,
 Thorsten

von M. H. (doktorgnadenlos)


Lesenswert?

Vielen Dank für die fundierten Infos, Thorsten.
Ich denke damit sollte ich weiterkommen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.