Forum: Compiler & IDEs ARM Bootloader mit ELF, Einstieg nicht bei 0x08000000


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

Hallo,
da schreibe ich grade an einem STM32 Bootloader, der per Modbus die 
Daten bekommt.
Der braucht natürlich noch ein Gegenpart, der wird grade in python 
geschrieben und ließt direkt das ELF ein.
Denn im ELF steht u.a als section noch ein struct für Metadaten zum 
Firmwarefile.

Das Funktioniert an sich schon, solange die Firmware bei 0x08000000 
startet.

Aber wenn die Firmware weiter hinten in den Flash soll, sagen wir 
0x08002c80, dann steht das nirgends im ELF.
Das fängt noch fröhlich bei 0x08000000 an.
Aber objcopy scheints trotzdem irgendwie zu erkennen und erzeugt ein 
Binary ab 0x08002c80.

Nur mein ELF Parsing gerät da an seine Grenzen, denn ich erkenne nicht 
wo das steht.

Im Linkerscript:
1
ENTRY(Reset_Handler)
2
SECTIONS{
3
4
  /* Flash Anfang */
5
  . = 0x08002c80;
6
  _flash_start = .;
7
  
8
  /* Das Programm kommt natürlich in den Flash */
9
  .text : {
10
    KEEP(*(.text.vectors)) /* NVIC Vektoren MÜSSEN an den Start! */
11
    KEEP(*(.text.handler)) /* oder die cpp irq handler werden wegen weak nicht genommen */
12
    *(.text*)
13
  }
14
  
15
  /* weiteres ist unwichtig */
16
}

Denn im elf wird nur die Programmgröße größer und .text startet jetzt ab 
0x08002c80.
Aber ich will ja nicht nur auf .text gucken, falls vllt irgendwann mal 
eine section davor kommt.

Im Anhang der Output eines elf scanners.

Da gibts jetzt ein "SHT_NULL" bei den sections, aber das hat keine 
Größe, sonst könnt ich mich daran orientieren.

Die segmente fangen immernoch fröhlich bei 0x08000000 an.

Nun die Frage:
Woran kann ich mich im ELF denn jetzt orientieren ab wann ich denn jetzt 
in den Flash schreiben soll?

Ich könnt jetzt als Workaround den Entrypoint auf den Flashanfang setzen 
statt dem Resethandler (weils beim STM32 eh egal is).
Aber das is eigentlich nicht so gedacht.

von W.S. (Gast)


Lesenswert?

Mw E. schrieb:
> Der braucht natürlich noch ein Gegenpart, der wird grade in python
> geschrieben und ließt direkt das ELF ein.

Der ursprüngliche Sinn eines Bootladers besteht darin, den von einer 
Toolchain erzeugten Maschinencode in den Chip zu kriegen. Also wäre es 
wohl das beste, es dabei zu belassen und sowas wie ein .elf (linked.axf 
usw.) File als intermediäre Datei der Toolchain anzusehen und sich nur 
auf die von fromelf erzeugten Dateien (Intel-Hex, Motorola-Hex, binär) 
zu stützen.

Denke einfach weiter und versuche lieber nicht, solche Programme wie 
fromelf etc. arbeitslos zu machen.

Abgesehen davon ist sowas wie ein eigener Bootlader per Modbus gerade 
bei Chips, die ohnehin einen Bootlader im ROM haben, nur für 
Firmware-Updates beim Kunden fällig. Und dazu gehört eine zuverlässige 
und vom Nichtfachmann benutzbare PC-Software dazu, die keinerlei 
Installation benötigt. Python ist nur für Kundensysteme brauchbar, wo 
ohnehin die Python-Laufzeit-Installation vorhanden ist.

W.S.

von pff (Gast)


Lesenswert?

Ach, W.S.
Mal wieder Leseschwäche?
Oder einfach keine Ahnung und Verständnis?

W.S. schrieb:
> Also wäre es
> wohl das beste, es dabei zu belassen und sowas wie ein .elf (linked.axf
> usw.) File als intermediäre Datei der Toolchain anzusehen
Post nicht gelesen?
Er will ort Metadaten auslesen.

W.S. schrieb:
> eine zuverlässige und vom Nichtfachmann benutzbare PC-Software
Wo schreibt er was von Kundensoftware?



W.S. schrieb:
> Denke einfach weiter und versuche lieber nicht, solche Programme wie
> fromelf etc. arbeitslos zu machen.
Sagt derjenige der Tobsuchtsanfälle bekommt wenn jemand die libc nutzt?
Das hast du selber nachgebaut, also halt dich bitte auch an deine 
eigenen Vorstellungen wenn du andere maßregelst!

von Johannes S. (Gast)


Lesenswert?

So richtig kann ich das Problem noch nicht nachvollziehen. In den 
Sections im ELF steht doch jeweils drin ob und wohin die geladen werden 
sollen, mehr machen andere Werkzeuge ja auch nicht. Wo dann die 
Startadresse sein soll, das muss der Bootloader ja wissen und für diese 
Adresse wird die Anwendung ja auch gelinkt.

von W.S. (Gast)


Lesenswert?

Johannes S. schrieb:
> So richtig kann ich das Problem noch nicht nachvollziehen.

Nun ja - ich vermute mal, daß der TO etwas basteln will, was objektiv 
gesehen nicht nötig ist. Und daß er die Gelegenheit benutzt, um seinen 
inneren Frust mal loszuwerden. Schlußendlich ist sowas ja immer abhängig 
vom ursprünglichen Systementwurf - und das ist nicht die Stärke des TO.

W.S.

von Johannes S. (Gast)


Lesenswert?

ich würde mal davon ausgehen das dieses Flashtool Teil eines komplexeren 
Systems ist und der TO schon seine Gründe dafür hat es so zu machen. In 
produktiven Umgebungen ist es durchaus sinnvoll solche Vorgänge zu 
automatisieren, für Leute die eine Baugruppe vorbereiten/testen müssen 
ohne Informatik studiert zu haben.

von Oliver S. (oliverso)


Lesenswert?

Mw E. schrieb:
> Denn im elf wird nur die Programmgröße größer und .text startet jetzt ab
> 0x08002c80.
> Aber ich will ja nicht nur auf .text gucken, falls vllt irgendwann mal
> eine section davor kommt.

Dann erzeuge doch mal so eine section davor, und schau nach, was dann im 
elf-file steht.

Oliver

von pff (Gast)


Lesenswert?

W.S. schrieb:
> Und daß er die Gelegenheit benutzt, um seinen
> inneren Frust mal loszuwerden. Schlußendlich ist sowas ja immer abhängig
> vom ursprünglichen Systementwurf - und das ist nicht die Stärke des TO.
Da kennt sich aber einer aus?

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Hmmm ... vielleicht hab ich den TO nicht richtig verstanden, aber warum 
legt man den Bootloader nicht an den Beginn des Flashes, und die 
Firmware (eigens lauffähiges Image) darüber (per Linker)?
Der Bootloader flasht dann die FW im Bedarfsfall neu, und bleibt somit 
auch bei einem Stromausfall beim Flashen erhalten.
Zum Starten der FW wird "FW StartAddr" (DWORD) +0 und +4 ausgelesen, 
VTOR und MSP gesetzt und diese am Reset Vector gestartet.
Nachteil: Das eigenständig lauffähige Image benötigt etwas mehr Speicher 
durch die "Aufdopplung" des C startup.

Ansonsten, wenn man sich mal im ELF vergraben will:
https://elfy.io/

von Andras H. (kyrk)


Lesenswert?

Random .. schrieb:
> Nachteil: Das eigenständig lauffähige Image benötigt etwas mehr Speicher
> durch die "Aufdopplung" des C startup.

Das ist meist nicht das Problem. Sondern eher die anderen Librarys wie 
zum Beispiel der USB stack oder Ethernet Stack. Man will ja vielleicht 
über Ethernet oder Wifi den Scheiss flashen...

C Startup ist fast nix.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Hab hier 64k für den Bootloader "reserviert", da drin liegen 
FlashFilesystem sowie ein AES Algo für die FW (von SD Card). TCP/IP und 
Webserver hab ich erstmal wieder rausgenommen, weil nicht benötigt, 
passt aber auch mit rein.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Hallo,
das drumrum hab ich mit Absicht weggelassen, mir gings nur ums ELF.
Komme aber weiter unten noch dazu um es abzurunden.


Johannes S. schrieb:
> So richtig kann ich das Problem noch nicht nachvollziehen. In den
> Sections im ELF steht doch jeweils drin ob und wohin die geladen werden
> sollen, mehr machen andere Werkzeuge ja auch nicht. Wo dann die
> Startadresse sein soll, das muss der Bootloader ja wissen und für diese
> Adresse wird die Anwendung ja auch gelinkt.
Gelinkt wird es nach "0x08002c80".
Aber in den Segmenten (nicht Sections) des ELF taucht immernoch fröhlich 
"0x08000000" auf.
Das verwundert mich.
Die beiden Segmente mit dem Typ "PT_LOAD" sind der Flash und der SRAM.
Die Startadresse kennt der Bootloader, aber eine Überprüfung ob man 
nicht ausversehen nach Flashanfang gelinkt hat wär schon nicht schlecht.


Oliver S. schrieb:
> Dann erzeuge doch mal so eine section davor, und schau nach, was dann im
> elf-file steht.
Eine Section, die 0x08000000 bis 0x08002c7f ausfüllt und weggeworfen 
wird oder wie?


Random .. schrieb:
> Hmmm ... vielleicht hab ich den TO nicht richtig verstanden, aber warum
> legt man den Bootloader nicht an den Beginn des Flashes, und die
> Firmware (eigens lauffähiges Image) darüber (per Linker)?
Genau das mach ich hier ja.
Der Bootloader wohnt ab 0x08000000 und die Anwendung soll nach 
0x08002c80.
Dorthin ist sie auch gelinkt, aber im ELF spiegelt sich das nicht 
wieder.


Random .. schrieb:
> Zum Starten der FW wird "FW StartAddr" (DWORD) +0 und +4 ausgelesen,
> VTOR und MSP gesetzt und diese am Reset Vector gestartet.
Wird auch gemacht, zum Glück hat der STM32L010 ein M0+ kern, sonst gäbs 
kein VTOR.
Aber noch kurz Interrupts beim rumspringen deaktivieren, sonst könnts 
lustig werden ;)


Random .. schrieb:
> Ansonsten, wenn man sich mal im ELF vergraben will:
> https://elfy.io/
Danke für den Link, da guck ich direkt mal rein.
Das zeigt mir die Segmente und Sections aber auch nicht groß anders an.


Andras H. schrieb:
> Sondern eher die anderen Librarys wie
> zum Beispiel der USB stack oder Ethernet Stack. Man will ja vielleicht
> über Ethernet oder Wifi den Scheiss flashen...
Modbus reicht.
Meine Modbuslib ist durchaus etwas größer geraten, da ich auch alle 
Events geloggt werden.
Für den Bootloader hau ich da eventuell noch ein par #ifdefs rein.


Random .. schrieb:
> Hab hier 64k für den Bootloader "reserviert"
So groß ist der ganze Flash des STM32L010K8 ;)

So, was solls denn jetz werden?
Das ist ein Wasserstandssensor für die Regentonne auf dem Balkon.
Damit werden die Tomaten automatisch Tröpfchenbewässert.
Aber wenn an mehreren Tagen hinternander 30°C+ sind ohne Regen, dann 
muss das früher aufgefüllt werden.
Da kann ich dann ausm urlaub die Verwandschaft anklingeln für einen 
gefallen.
Gib ja dann auch Tomaten zu ernten ;)

Das Ding ist in der hintersten Ecke des Balkons unter dem Regal der 
Tonne. Für ein FW Update will ich in das wasserdichte keine extra 
Buchsen einbauen und aufschrauben für SWD is auch blöd.
Daher über Modbus, das liegt ja schon da.

Mein Würgaround erstmal ist, dass ich die Sections nach Startadresse 
sortiere, da hab ich dann als kleinste Adresse die gelinkte Adresse.
Das funktioniert, aber gefällt mir nicht.

W.S. schrieb:
> dämliches Gesülze
Im Forum ist doch hinreichend bekannt, dass du keine Ahnung hast.
Dies den Leuten andauernd auf die Nase zu binden ist einfach nurnoch ... 
störend.
Ich zitiere daher einen anderen Forennutzer:
Johannes S. schrieb:
> Jeder ausser W.S. hat die Frage verstanden.
Noch als Tipp für dich wofür elf steht: Executable and Linking Format.
Also sei leise.
Für Argumente außerhalb deines schmalen Tellerrands biste eh nicht 
zugänglich.

: Bearbeitet durch User
von Random .. (thorstendb) Benutzerseite


Lesenswert?

Mw E. schrieb:
> Dorthin ist sie auch gelinkt, aber im ELF spiegelt sich das nicht
> wieder.

Häufig ist die Basisadresse im ELF eine recht "glatte" Adresse, auf die 
dann ein Offset kommt. Soll heissen: Die Section beginnt bei 0x0000, 
aber das erste Datum kommt erst bei 0x1000.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Random .. schrieb:
> Häufig ist die Basisadresse im ELF eine recht "glatte" Adresse, auf die
> dann ein Offset kommt. Soll heissen: Die Section beginnt bei 0x0000,
> aber das erste Datum kommt erst bei 0x1000.

Ja, genau das ist ja hier zu sehen.
Aber wo steht denn der (globale) Offset?

Bzw ist es denn definiert, dass die Section Liste immer 
Adressaufsteigend sortiert ist?
Das hab ich jetzt ehrlich gesgat nicht gefunden wo das steht.
Dann könnt man ja in der Liste nach dem ersten Typ "SHT_PROGBITS" gucken 
dessen Adresse nicht 0 ist.

von Oliver S. (oliverso)


Lesenswert?

Mw E. schrieb:
> Oliver S. schrieb:
>> Dann erzeuge doch mal so eine section davor, und schau nach, was dann im
>> elf-file steht.
> Eine Section, die 0x08000000 bis 0x08002c7f ausfüllt und weggeworfen
> wird oder wie?

Egal. Wenn du jetzt schon für den (anscheinend völlig 
unwahrscheinlichen) Fall vorsorgen willst, daß da irgendwann mal 
irgendeine irgendwie geartete Section davor kommt, dann mach halt 
einfach eine dort hin. Was da drin steht, ist doch völlig egal, du 
willst ja nur sehen, was sich dann im elf-File verändert.

Wenn da keine Section davor steht, ist es doch auch völlig sinnlos, das 
.text-Segment weiter hinten beginnen zu lassen.

Oliver

: Bearbeitet durch User
von Random .. (thorstendb) Benutzerseite


Lesenswert?

Mw E. schrieb:
> Ja, genau das ist ja hier zu sehen.
> Aber wo steht denn der (globale) Offset?
Kein Offset, der irgendwo eincodiert ist, sondern das erste Datum 
beginnt erst ab +irgendwas zum Section Offset.

Section Adresse: 0x08000000
Erstes Datum: 0x2c80

Lad doch mal das .elf hier hoch.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

Random .. schrieb:
> Lad doch mal das .elf hier hoch.

Bitteseher, siehe Anhang.

Oliver S. schrieb:
> Egal. Wenn du jetzt schon für den (anscheinend völlig
> unwahrscheinlichen) Fall vorsorgen willst, daß da irgendwann mal
> irgendeine irgendwie geartete Section davor kommt, dann mach halt
> einfach eine dort hin. Was da drin steht, ist doch völlig egal, du
> willst ja nur sehen, was sich dann im elf-File verändert.

Werd ich dann mal ausprobieren.
Da ich meine Linkerscripte selber schreibe könnte da durchaus mal was 
"perverses" drinne stehen haben ;)

von Random .. (thorstendb) Benutzerseite


Angehängte Dateien:

Lesenswert?

fromelf.exe --text -vacdegrstyz main.elf > out.txt

PHDR0 ist mir nicht klar - ist der nicht idR. leer? Oder ist das beim 
gcc anders?
1
** Program header #1
2
3
    Type          : PT_LOAD (1)
4
    File Offset   : 0 (0x0)
5
    Virtual Addr  : 0x08000000
6
7
8
    _flash_start
9
        0x08002c80:    20002000    . .     DCD    536879104
10
        0x08002c84:    080047c9    .G..    DCD    134236105

Hmmm ... auch nett :-)
https://onlinedisassembler.com/odaweb/0amrAP3l

: Bearbeitet durch User
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Random .. schrieb:
> PHDR0 ist mir nicht klar - ist der nicht idR. leer? Oder ist das beim
> gcc anders?

Ich weis auch nicht wieso er da den PT_ARM_EXIDX hinpackt.
Laut dem Artikel hier macht das eigentlich der LLVM, aber der GCC tuts 
auch:
http://sushihangover.github.io/llvm-and-the-arm-elf-arm-dot-exidx-star-section/

Random .. schrieb:
> Hmmm ... auch nett :-)
> https://onlinedisassembler.com/odaweb/0amrAP3l

Der merkt sich sogar die elf!

von pff (Gast)


Lesenswert?

Ich habe recherchiert.
Auch darin hat W.S: nicht recht:

W.S. schrieb:
> die keinerlei
> Installation benötigt. Python ist nur für Kundensysteme brauchbar, wo
> ohnehin die Python-Laufzeit-Installation vorhanden ist.

Er kann wenig, er weis wenig!
Aber immer ein Großmaul!

Siehe: http://www.py2exe.org

Nachtrag: Der Verbreitung von Java hat es auch nicht geschadet vorher 
eine JRE zu installieren.

von gnuopfer (Gast)


Lesenswert?

> Nachtrag: Der Verbreitung von Java hat es auch nicht geschadet vorher eine JRE 
zu installieren.

Pruuuust .... Mist, jetzt brauch ich ne neue Tastatur.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

So, läuft!

Zwar immernoch mit dem Würgaround, aber die GUI ist jetzt auch fertig.

von Blume (Gast)


Lesenswert?

Kannst du vielleicht doch mal dein Linker Script veröffentlichen ???

von speed (Gast)


Lesenswert?

lol @ 600Bytes/s
Da updated die NASA ihren Marslander schneller.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

Im Anhang mal das Linkerscript.

Inzwischen ist schon längst die Baudrate hochgedreht, die Hardware CRC 
aktiv und Halfpage Flash write implementiert.
Jetzt ist kein großer Unterschied meh zwischen Bootloader und J-Link zu 
bemerken.

von Christian T. (chris94)


Lesenswert?

Habe das gleich Problem...
Wurde hier eine Lösung gefunden mit der die ELF nicht direkt in den 
ersten Sektor geschrieben wird?

VG Chris

von M. H. (bambel2)


Lesenswert?

Christian T. schrieb:
> Habe das gleich Problem...
> Wurde hier eine Lösung gefunden mit der die ELF nicht direkt in den
> ersten Sektor geschrieben wird?

Gibt mehrere Möglichkeiten:

1. Hau drauf Methode: Man passt den Speicher im Linkerscript an und 
gaukelt dem Linker vor, dass der Flash einfach woanders anfängt.

2. Man packt eine "noload" section an den Anfang des flashs, die die 
ersten x bytes verschluckt


Und abschließend: Sections sind für das Laden des Programms an sich 
irrelevant.
Die sind nur wichtig für Linking etc. Segments sind das Stichwort, 
wenn man herauskriegen will, was man laden muss. Siehe online Suche "ELF 
section vs segment"

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]
  • [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.