mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Checksum GNU-Linker


Autor: Daniel_s (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Ich möchte gerne in einem Programm zur Laufzeit verifizieren, ob ein 
Programmcode noch richtig im Flash steht. Dies würde ich gern mit einer 
Checksum über das Programmsegment machen. Nun wollte ich fragen ob es in 
der GNU-Toolchain eine Option gibt, die den Linker veranlasst an einer 
bestimmten Stelle im Programmcode diese Checksum zu schreiben. Ich bin 
für alle Anregungen dankbar.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Toolchain selbst nicht, aber du kannst sowas immer noch nachher
machen -- im Zweifelsfalle erst auf der Ebene der Hex-Datei.

Zweistufig geht es auch mit dem Linker: du erfindest eine eigene
section für die Prüfsumme, die du mit einem einzelnen Symbol belegst.
Im ersten Linkerdurchlauf setzt du dieses Symbol erstmal auf 0 (damit
es überhaupt belegt ist) und linkst alles zusammen.  Danach berechnest
du für den dich interessierenden Teil (text oder text + data) die
Prüfsumme und linkst das Ganze nochmal.  Diesmal gibst du die
ermittelte Prüfsumme dem Linker über die Option --defsym mit, damit
es das spezielle Symbol auf ebendiesen Wert setzt und selbigen dann
in die zugehörige section einträgt.

Autor: Daniel_s (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja wenn ich das nur ein mal nach Beendigung aller Entwicklungsarbeit 
machen müsste wär das schon gut. Leider ist es Teil einer Entwicklung 
die noch nicht abgeschlossen ist und an der mehrere mitarbeiten und so 
müsste man nach jeder Änderung von Hand die Checksumme berechnen und 
eingeben.

Der Linker XLINK von IAR hat eine Option die genau das ermöglicht. 
Leider siehts bei Gnu schlecht aus. Oder täusche ich mich?

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum? Jörg hat doch grad beschrieben wie das geht.

Einfach diese Schritte ins Makefile einbinden, => bei jeden neuen Build 
wird automatisch die Checksum neu berechnet und eingebunden.

Autor: Daniel_s (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Jörg für den Tip. Hab erst jetzt gesehen, dass du noch mehr 
geschrieben hattest.

Das zweistufige ist schon ganz gut. Das Problem ist halt, dass man immer 
mit einem externen Programm die CRC berechnen muss. Aber es wird wohl 
nicht anders gehen

Autor: Daniel_s (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das stimmt, in ein MAkefile könnte man das einbinden. Ich benutzte 
halt die IDE von Anglia und da gibts wohl kein makefile im eigentlichen 
Sinne. Ich schau mal ob man das zweistufige vorgehen irgentwie sonst 
einbinden kann. Sonst muss ich ein makefile machen

Autor: Siddhartha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

ich weiss der Thread ist schon einige Monate alt, aber da er genau das 
Thema behandelt, das mich beschäftigt, wollte ich nicht extra einen 
neuen aufmachen.

Also ich will ebenfalls beim Compilieren ganz am Ende des Codes einen 
CRC16 einfügen. Ich benutze die GNU ARM Toolchain von Yagarto.
Ich führe zuerst arm-elf-gcc aus und lasse alles kompilieren und linken. 
Ein kleines Tool, das den CRC berechnet habe ich bereits geschrieben und 
wollte dann im Makefile mit --defsym (wie oben empfohlen) den 
berechneten CRC-Wert des vorher generierten BIN-Files nochmals an den 
Linker übergeben. Doch irgendwie wird der CRC-Wert von meinem 
Linker-Script nicht angenommen bzw nicht richtig 
interpretiert/verwendet. Irgendwie habe ich das Gefühl, dass ich die 
--defsym Option falsch verstanden habe.

Die ensprechende Zeile in meinem Makefile sieht folgendermassen aus:
arm-elf-gcc $(LDFLAGS) -Xlinker --defsym -Xlinker CRC16=0x$(shell crc16 $(OUTFILE).bin) -n -o $(OUTFILE).elf $(OBJECTS)
arm-elf-objcopy --strip-debug --strip-unneeded $(OUTFILE).elf -O binary $(OUTFILE).bin

(Zwischenfrage: Wird bei solch einem Aufruf nochmals alles neu 
kompiliert oder direkt der Linker aufgerufen?)

Im Linker-Script sieht es folgendermassen aus (nur der relevante Teil):
...
__CRC_START__  = 0x03FFFE; /* 2 Bytes for Flash-Ende */
PROVIDE(CRC16 = 0x0000)

SECTIONS
{
    ...
    
    crc : AT( __CRC_START__)
    {
        SHORT(CRC16);
    } = 0xFFFFFFFF

    ...
}

Komischerweise steht im MAP File dann folgendes:
crc             0x0020adfc        0x2 load address 0x0003fffe
                0x0020adfc        0x2 SHORT 0x0 CRC16
                0x0020adfe                PROVIDE (end, .)
                0x0000d8ca                CRC16 = 0xd8ca

Also irgendwie kriegt er den Wert zwar, aber er interpretiert ihn direkt 
als Adresse und nicht irgendwie als Variable.

Ich wäre sehr froh, wenn mich jemand aufklären könnte, ob ich das 
Konzept mit --defsym komplett falsch verstanden habe oder ob ich einfach 
sonst einen Newbie-Fehler gemacht habe.

Danke!
Mit freundlichen Grüssen

Siddhartha

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.