Forum: Compiler & IDEs Bootloader.elf & Application.elf mergen / kombinieren


von ELF-Flasher (Gast)


Lesenswert?

Hallo zusammen,

ich hab 2 ELFs für AVR:
1. ./default_2/Application.elf
2. ./default_btl/Bootloader.elf (kompiliert mit .text=0x1E000)

Ziel:
Beide sollen in 1 ELF, Fuses & Lockbits aus Application übernehmen.

Klar hab ich gegoogelt und sowohl hier als auch in anderen Foren bereits 
einiges dazu gesehen, ich wende mich an Euch, weil ich dennoch nicht 
weiter komme...

schaut man in die ELFs zeigt sich folgendes für den Bootloader:
avr-readelf -S ./default_btl/bootloader.elf
1
There are 7 section headers, starting at offset 0x18fc:
2
3
Section Headers:
4
  [Nr] Name         Type            Addr     Off    Size   ES Flg Lk Inf Al
5
  [ 0]              NULL            00000000 000000 000000 00      0   0  0
6
  [ 1] .data        PROGBITS        00800200 0018a8 000028 00  WA  0   0  1
7
  [ 2] .text        PROGBITS        0001e000 0000d4 0017d4 00  AX  0   0  2
8
  [ 3] .bss         NOBITS          00800228 0018d0 0006ab 00  WA  0   0  1
9
  [ 4] .fuse        PROGBITS        00820000 0018d0 000003 00  WA  0   0  1
10
  [ 5] .lock        PROGBITS        00830000 0018d3 000001 00  WA  0   0  1
11
  [ 6] .shstrtab    STRTAB          00000000 0018d4 000028 00      0   0  1

und folgendes für die Applikation:
avr-readelf -S ./default_2/Application.elf
1
There are 8 section headers, starting at offset 0xba7c:
2
3
Section Headers:
4
  [Nr] Name         Type            Addr     Off    Size   ES Flg Lk Inf Al
5
  [ 0]              NULL            00000000 000000 000000 00      0   0  0
6
  [ 1] .data        PROGBITS        00800200 00b7c2 000184 00  WA  0   0  1
7
  [ 2] .text        PROGBITS        00000000 0000f4 00b6ce 00  AX  0   0  2
8
  [ 3] .fw_data     PROGBITS        0001df00 00b946 000100 00   A  0   0  1
9
  [ 4] .bss         NOBITS          00800384 00ba46 00069a 00  WA  0   0  1
10
  [ 5] .fuse        PROGBITS        00820000 00ba46 000003 00  WA  0   0  1
11
  [ 6] .lock        PROGBITS        00830000 00ba49 000001 00  WA  0   0  1
12
  [ 7] .shstrtab    STRTAB          00000000 00ba4a 000031 00      0   0  1

Ich habe es also mit avr-objcopy probiert:
1
avr-objcopy --add-section .bootloader=Bootloader.elf Application.elf
--> .bootloader taucht dann zwar auf, aber bei Addr. 0, also:
1
avr-objcopy --change-section-address .bootloader=0x1e000 Application.elf
--> .bootloader taucht an richtiger (Byte-)Adresse auf: 0x1E000, jedoch 
ohne Flags, also:
1
avr-objcopy --set-section-flags .bootloader=code,readonly Application.elf

und das kommt raus:
avr-readelf -S ./default_2/Application.elf
1
There are 9 section headers, starting at offset 0xd4a4:
2
3
Section Headers:
4
  [Nr] Name         Type            Addr     Off    Size   ES Flg Lk Inf Al
5
  [ 0]              NULL            00000000 000000 000000 00      0   0  0
6
  [ 1] .data        PROGBITS        00800200 00b7c2 000184 00  WA  0   0  1
7
  [ 2] .text        PROGBITS        00000000 0000f4 00b6ce 00  AX  0   0  2
8
  [ 3] .fw_data     PROGBITS        0001df00 00b946 000100 00   A  0   0  1
9
  [ 4] .bss         NOBITS          00800384 00ba46 00069a 00  WA  0   0  1
10
  [ 5] .fuse        PROGBITS        00820000 00ba46 000003 00  WA  0   0  1
11
  [ 6] .lock        PROGBITS        00830000 00ba49 000001 00  WA  0   0  1
12
  [ 7] .bootloader  PROGBITS        0001e000 00ba4a 001a1c 00   X  0   0  1
13
  [ 8] .shstrtab    STRTAB          00000000 00d466 00003d 00      0   0  1

Ich flashe die so erstelle Application.elf ins Target.
Er bootet dort in die Application, springt dann zum Bootloader mit:
1
void (*start)( void ) = 0xF000; // word-adr of bootloader start
2
start();
Nach dem Sprung zuckt das Display kurz, danach ist er leider wieder in 
der Application.
Testweise lasse ich den Bootloader blinken und Chars am UART ausgeben. 
Beides ist nach dem Sprung nicht zu sehen.

Folgendes funktioniert:
Bootloader.hex flashen
Bootloader.hex flashen (ohne Erase Device)
--> jump to 0xF000 ... blinkt und zeigt Chars am UART

--> Der Fehler muss also in meiner avr-objcopy Akrobatik liegen.


Was auffällt:
- die "size" von .text in Bootloader.elf ist nur 17d4
- die "size" von .bootloader in Application.elf ist 1a1c

Frage:
- wie kann man die beiden ELFs wie gewünscht mischen?

: Verschoben durch Moderator
von Bernd K. (prof7bit)


Lesenswert?

Probier mal stattdessen die Hex-dateien zu kombinieren, das dürfte 
wesentlich einfacher sein, brauchst auch keine speziellen Tools dazu 
denn das ist Plaintext, musst nur beim ersten den End-of-file Record 
entfernen. Kann man auch gut scripten. Siehe auch: 
https://de.wikipedia.org/wiki/Intel_HEX

: Bearbeitet durch User
von ELF-Flasher (Gast)


Lesenswert?

Hallo Bernd,

hex mergen klappt schon, funktioniert mit diversen Möglichkeiten, ein 
combi.hex zu bauen.

Kennst Du einen Weg, aus so einem combi.hex ein combi.ELF (inkl. Fuse & 
Lock -Bits) zu erstellen?

war vorhin ein Tippfehler...
Folgendes funktioniert:
Application.hex flashen
Bootloader.hex flashen (ohne Erase Device)
--> jump to 0xF000 ... blinkt und zeigt Chars am UART
--> Bootloader kann aus App angesprungen werden

Viele Grüße

von holger (Gast)


Lesenswert?

>Kennst Du einen Weg, aus so einem combi.hex ein combi.ELF (inkl. Fuse &
>Lock -Bits) zu erstellen?

Das geht nicht. In der HEX Datei gibt es keine Sections mehr
die man in eine ELF Datei packen könnte. Das eigentliche
Problem sind ja wohl auch nur die Fuses und Lockbits.

von ELF-Flasher (Gast)


Lesenswert?

Wir haben 2 Projekte mit allen Sourcen:
1. Application.elf
2. Bootloader.elf

daraus kann man ihex machen & diese kombineren zu combi.hex.
combi.hex hab ich aufgespielt --> App & Boot lassen sich nutzen.

Könnte man nun ein vollwertiges combi.elf generieren aus
- combi.hex und aus
- den Fuse- Lock-Infos aus Application.elf
??

von ELF-Flasher (Gast)


Lesenswert?

Es gibt eine Reihe von Infos und Diskussionen zu dem Thema,
leider noch ohne Lösung für mich...

Referenz für OBJCOPY:
https://linux.die.net/man/1/objcopy

Memory Sections:
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

ELF:
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#Section_header

ein Makefile-Snipsel, um ein binary mit zu verlinken:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_binarydata

Gleiches Problem wie mein Thread, aber ohne Lösung für mich:
Beitrag "Re: AVR Bootloader + Hauptprogramm zusammenfügen"
Marc beschreibt hier die Möglichkeit, jede Funktion einzeln in die 
.bootloader section zu verschieben.
Ich nutze in meinem Code z.B. memset(). Wie verschiebt man das?
Da mir dazu nichts eingefallen ist, hab ich den Bootloader einfach mit 
folgendem Linker-Hinweise übersetzt:
1
-Ttext=0x1E000

Außerdem nutzen mein Bootloader & Application teils gleiche C-Files mit 
gleichen Funktionsnamen.
Wie kann man sowas zusammenbauen / linken?

von ELF-Flasher (Gast)


Lesenswert?

Jetzt hab ich einen Modus, der für mich funktioniert ....

Schritt 1: ./default_btl/bootloader.elf bauen mit .text=0x1E000
Schritt 2: daraus ein verlinkbares Objekt erzeugen mit einem Script:
1
avr-objcopy -S --rename-section .text=.btl_text,contents,alloc,load,readonly,data ./default_btl/bootloader.elf ./default_btl/bootloader_link.o
2
avr-objcopy -j .btl_text ./default_btl/bootloader_link.o

Schritt 3: im Makefile der Applikation:
3a) Adresse der Section .btl_text bekannt machen:
1
LDFLAGS += -Wl,-section-start=.btl_text=0x1e000
3b) zu app_file1.o app_file2.o noch den Bootloader linken:
1
LINKONLYOBJECTS = ..\default_btl\bootloader_link.o
(Ich hab hier einfach ein Makefile des AVR-Studio4 abgeändert)

Schritt 4: ./default2/application.elf bauen

..fertig
application.elf enthält nun auch den Bootloader in der section .btl_text 
auf Byte-Adresse 0x1E000 (=0xF000 Word-Adresse).

Aus bootloader.elf hab ich lediglich .text extrahiert, da ich momentan 
noch nicht so recht wusste, wie die .data section im Makefile der 
application zu verlinken und zu addressieren ist.

>>Vielleicht hat dazu noch jemand einen Vorschlag.<<

--> diese Lösung funktioniert also nur, wenn der Bootloader-Code auf 
.data verzichten kann! (Variablen-Initialisierung fällt also weg)

von Stefan E. (sternst)


Lesenswert?

ELF-Flasher schrieb:
> Aus bootloader.elf hab ich lediglich .text extrahiert, da ich momentan
> noch nicht so recht wusste, wie die .data section im Makefile der
> application zu verlinken und zu addressieren ist.
>
>>>Vielleicht hat dazu noch jemand einen Vorschlag.<<

Du könntest einen kleinen Umweg über ein Binary machen.
Dazu Schritt 2 ersetzen durch:
1
avr-objcopy -j .text -j .data -O binary ./default_btl/bootloader.elf ./default_btl/bootloader.bin
2
avr-objcopy --rename-section .data=.btl_text,contents,alloc,load,readonly,data -I binary -O elf32-avr ./default_btl/bootloader.bin ./default_btl/bootloader_link.o

von Karl (Gast)


Lesenswert?

Peter Danegger hat mir hier mal den wertvollen Tipp gegeben, die 
Applikation unbedingt mit dem bootloader zu flashen.  Danach hast Du 
zwar nicht gefragt, aber ich halte das für wichtig.

Zum Thema: srecord heißt zwar nicht so, kann aber recht viel.

von ELF-Flasher (Gast)


Lesenswert?

Stefan E. schrieb:

> Du könntest einen kleinen Umweg über ein Binary machen.
> Dazu Schritt 2 ersetzen durch:

Das hat prima funktioniert!
Witzig, durch den *.bin - Zwischenschritt werden .text und .data in eine 
gemeinsame .text gesteckt, die dann nachher so einfach in die .btl_text 
wandern kann.

@Karl:
Ja ... hab auch gerade ein eigentümliches Verhalten:
Flashe ich den Bootloader und über diesen die App --> alles gut
Flashe ich Boot & App gemeinsam, springe dann den Boot an, so hängt er 
dann irgend wo im Nirvana... Der Program-Counter ist bei 0xE.... da 
sollte momentan gar kein Code sein.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

holger schrieb:
> Das geht nicht.

Kannst du so nicht sagen.

> In der HEX Datei gibt es keine Sections mehr
> die man in eine ELF Datei packen könnte.

Die könnte man ja wieder synthetisieren, indem man zu jeder HEX-Datei
angibt, in welcher ELF-Section sie landen soll.

Aber ich kenne auch kein fertiges Tool, welches sowas anbietet.

von Bernd K. (prof7bit)


Lesenswert?

Ich bin übrigens mittlerweile bei mir dazu übergegangen nicht mehr zu 
versuchen alles in eine Datei zu quetschen, stattdessen hat sich 
rausgestellt daß ich sowieso für jedes Produkt ein selbstgestricktes 
Produktions-Tool brauche mit dem in der Produktion dann geflasht wird, 
eeprom daten je nach gewünschter Konfiguration erzeugt und geflasht 
werden, etc. also verteile ich alle Dateien die draufgeflasht werden 
sollen separat und das jeweilige Tool flasht die dann einfach alles was 
bei dem Produkt drauf muss der Reihe nach drauf.

Da Bootloader und Anwendungen hier in separaten Repositories gepflegt 
werden spare ich mir bei jedem Update eines Teils den Aufwand jedesmal 
wieder die anderen Teile von anderswo einsammenzusammeln und alles 
zusammenzumergen (man stelle sich vor ich fände einen Bug im Bootloader, 
dann wäre ich einen halben Tag lang beschäftigt neue Firmwarefiles für 
alles neu zu generieren, zu testen und zu deployen), ich tausche 
stattdessen einfach auf der Produktionsmaschine die eine einzige Datei 
aus, die anderen bleiben wie sie sind und zusammengeführt wird es erst 
beim Flashen selbst. Find ich einfacher zu handhaben.

Für Produkte die der Kunde selbst updaten können soll bekommt er 
ebenfalls nicht einfach nur eine nackte Datei und kryptische Anweisungen 
sondern er bekommt ein idiotensicher zu bedienendes Windows-Tool das 
falls nötig auch mehrere einzelne Firmwaredateien im Bauch hat und die 
an Ort und Stelle mit einem Mausklick automatisch einzeln in der 
richtigen Reihenfolge aufspielt.

: Bearbeitet durch User
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.