Christians Webseite        << zurueck        vor >>

Der OWL Bootloader

Bei meiner Suche nach einem "guten" Bootloader für Atmel-Prozessoren bin ich auf dieser Webseite gelandet.
Der Autor, Julien Thomas, stellt dort seinen "One-Way-Loader" vor:

OWL

Die Bezeichnung exzellent trifft es am besten! Das Konzept und die Umsetzung finde ich hervorragend. Meinen grössten Respekt vor dieser grossen Arbeit.


Dieser Bootloader ist für alle gängigen Controller der TinyAVR und MegaAVR Familie geeignet und sehr flexibel konfigurierbar. Als Programmierschnittstelle kann praktisch alles, was an einem Port, hängt verwendet werden. Eine kryptographische Absicherung ist direkt mit implementiert.

(Die von mir verwendeten Begriffe wie "Kodierung" oder "Verschlüsselung" sind vermutlich wissenschaftlich nicht ganz sauber..)

Die Vorgehensweise

Das Programmpaket enthält ein (Windows-)Programm (OWL.exe) und diverse Binär-Dateien mit Bootloader-Templates für jeden Prozessortyp. Das ZIP muss nur entpackt und abgespeichert werden. Die Ordnerstruktur darf nicht verändert werden.

Mit dem OWL-Programm generiert man einen individuell zugeschnittenen Bootloader. Als Basis werden dabei die mitgelieferten Templates benutzt, der Code wird automatisch passend gepatcht. Der Bootloader wird danach, ganz klassisch per ISP-Programmer, in den Prozessor geschrieben.

Die zu ladende Firmware wird mit dem Programm kodiert bzw encrypted (mit "Firmware" ist hier das eigentliche Haupt-Programm für den Atmel gemeint).

Das Laden der kodierten Firmware auf den Prozessor erfolgt über die bei der Bootloader-Erstellung konfigurierte Methode, im üblichen Fall über eine UART-Schnittstelle.

Besonderheiten

Über die Kodierung der Firmware wird eine effektive Methode implementiert um eine robuste Übertragung zu erreichen und Fehler zu vermeiden. Nebenbei wird auch die Firmware verschlüsselt. Das ist für einfache Anwendungen nicht wirklich nötig, schadet aber auch nicht.

Für die Kodierung einer Firmware muss immer auch die zugehörige Bootloader-Datei vorliegen. Sie enthält die individuellen Schlüssel.

Das OWL-Programm ist eine Kommandozeilen-Anwendung mit vielen möglichen Parametern. Besonders für Einsteiger, oder bei nur gelegentlicher Nutzung, ist das etwas lästig und verwirrend. Man sollte sich daher ein paar vordefinierte Batch-Dateien anlegen.
Zur bequemeren Bedienung habe ich mir deshalb eine Windows-GUI gebaut die alle Aktionen bündelt.
Atmel

Der Bootloader bringt seine eigene Software-UART Implementierung mit. Er kann daher auf jeden Port-Pin konfiguriert werden. Ein Rück-Kanal zur Synchronisierug ist nicht zwingend notwendig (daher der Name: One-Way-Loader). Das richtige Timing wird automatisch erkannt und eingestellt.

Beim Flashen des Bootloaders muss auf die korrekten Fuse- und Lock-Bits geachtet werden.

  • Die Fuse-Bits müssen passend zur späteren Firmware konfiguriert werden, z.B. Clock, Brown-Out und Watch-Dog
  • Der Bootloader hat einen Speicherbedarf von 512 Byte, BOOTSZ muss auf einen Wert >= gesetzt werden
  • Der Boot-Reset-Vector (BOOTRST) muss aktiviert werden
  • Das Lock-Byte sollten beim Experimentieren am besten erstmal ungesetzt bleiben (0xFF). Bei erhöhten Sicherheitsanforderungen kann man den Bootloader-Bereich später sperren
  • Die LB-Bits sind unproblematisch und können auf [0,0] gesetzt werden (= alles geschützt)
  • Ebenso die BLB1-Bits([0,0] = Mode 3). Das verbietet ein Lesen/Schreiben im Bootloader-Bereich
  • Die BLB0-Bits müssen im Mode 1 bleiben ([1,1]) damit der Bootloader das Anwendungsprogramm überscheiben kann
  • Das resultierende Lock-Byte für einen ATmega328P (als Beispiel) ist 0xCC (= 0b1100 1100)

Sequenzen

Das Arbeiten mit OWL lässt sich in 3 Phasen einteilen:

  • Bootloader erstellen
  • Bootloader ins Target laden mit AVRdude
  • Firmware kodieren und übertragen
Ein wenig Aufmerksamkeit benötigt dabei die Namensgebung von OWL:
  • <targetname>: der Bootloader
  • <flashfile>: das originale "User"-Programm vor dem Kodieren
  • <transfile>: das kodierte "User"-Programm im "OWL-Format"

Einige Batch-Beispiele:

Bootloader erstellen
Der neu erstellte Bootloader wird unter dem Namen <targetname> abgespeichert.
owl.exe --device=m168P --rxport=D0 --txport=D1 --clock=8000 --timeout=255 --targetname=owl_loader_m168pb_d0.hex"
Bootloader ins Target laden mit AVRdude
Das Flashen wird nicht mit OWL.exe gemacht sondern mit AVRdude.exe. Es ist nur einmalig nötig.
avrdude.exe -p m168PB -P COM3 -b 115200 -B 20 -c stk500v2 -e -U lfuse:w:0xE2:m -U hfuse:w:0xDF:m -U efuse:w:0xFD:m -B 1.1 -U flash:w:"C:\OWL_Bootloader\targets\owl_loader_m168pb_d0.hex":i
Firmware kodieren und übertragen
Die eigentliche Programmdatei <flashfile> wird in das OWL-Format kodiert und direkt per COM-Port an das Target übertragen. Dieser Schritt muss für jedes Update der Programmdatei wiederholt werden. Die Bootloader-Datei <targetname> muss dazu zwingend vorhanden sein.
owl.exe --targetname=owl_loader_m168pb_d0.hex --flashfile=Test_1.hex --serialport=COM8 --baud=9600

Weitere Sequenzen

Das Kodieren und Übertragen der Firmware wird im Beispiel in einem Schritt zusammengefasst. Es kann aber Situationen geben in denen man diese beiden Schritte trennen möchte oder muss, z.B. wenn eine neue, kodierte Firmware zum Updaten weitergegeben wird. Die Bootloader-Datei ist in diesem Fall nicht verfügbar.

Das OWL-Programm erzeugt beim Kodieren automatisch im Hintergrund eine Datei die alle Übertragungdaten enthält. Sie wird im "transmissions"-Verzeichnis unter einem automatisch genriertem Namen abgelegt.
<date><time>__<target_filename>_<bootloader_filename>.owl
Diese Datei ist für eine Weitergabe gedacht.

Firmware nur kodieren, keine Übertragung
owl.exe --targetname=owl_loader_m168pb_d0.hex --flashfile=Test_1.hex
Eien bereits fertig kodierte Programmdatei übertragen
owl.exe --transfile=20240130__Test_1_owl_loader_m168pb_d0.owl --serialport=COM8 --baud=9600 Diese Übertragung ist ein simples binäres Verschicken über eine COM-Schnittstelle. In einer Windows-Umgebung könnte man auch eine Batch-Sequenz verwenden:
mode COM1 9600,n,8,1
copy /b 20240130__Test_1_owl_loader_m168pb_d0.owl COM1

Ebenso ist jedes Windows-Terminal-Programm dafür geeignet.

Optionen

Die möglichen Parameter-Optionen für das Programm sind sehr umfangreich. Eine Hilfsseite kann mit "owl.exe -h" aufgerufen werden. Detailliertere Bescheibungen finden sich im Quelltext. Die Parameter können in Lang- oder Kurzform benutzt werden (z.B.: -h oder --help).

Single Commands die nur Informationen ausgeben: --help
--license
--supported
--ownloaders
--transmissions
--version
--key

Basic Setup, single command für Spezialisten:
--randpool
Flags:
--verbose
--eepromerase
--flasherase

Parameter mit Zahlenangaben oder Dateinamen:
--device= das Kürzel für den Atmel-Prozessortyp, z.B. "m328p"
--baud= Baudrate für die Übertragung, z.B. "2400"
--clock= Die Taktfrequenz des Prozessor in kHz, z.B. "8000"
--timeout= Zeitspanne nach dem Booten innerhalb der auf eine Übertragung geprüft wird (8-Bit Wert, 100 entspricht 1.00 Sekunden, max 2.55 Sekunden)
--number= Anzahl der Bootloader die erstellt werden sollen, für Serienerstellung
--rxport= Port des Atmels auf dem Daten empfangen werden, z.B. "D0"
--txport= Port des Atemls auf dem Daten gesendet werden, z.B. "D1" (optional)
--targetname= Dateiname des neu generierten Bootloaders
--serialport= Serieller Port des PC für die Firmware Übertragung, z.B. "COM1"
--audiofile= Dateiname um die kodierte Firmware als WAV abzuspeichern
--remark= Anmerkungen die als Kommentar an den Binärcode des Bootloaders angehängt werden
--intpreamble= Länge der Präambel für die seriellen Übertragung, default 1.00 Sekunden
--outpreamble= Länge der zusätzlich angehängten Dummy-Sequenz nach der Übertragung, default 0.10 Sekunden
--eepromfile= Datei die in den Eeprom-Bereich geladen werden soll
--flashfile= Datei die in den Flash-Bereich geladen werden soll (die neue Firmware)
--transfile= Dateiname der kodierten Firmware
--encrypt= Dateiname für Test der Verschlüsselung
--decrypt= Dateiname für Test der Entschlüsselung

Probleme

OWL machte alles richtig, aber meine PC-Umgebung nicht.

Mit der Übertragung der .owl-Dateien über einen COM-Port hatte ich anfangs massive Probleme. Kleine Dateien wurden problemlos übertragen, grössere nicht. Die Ursache lag bei dem verwendeten USB-UART Umsetzer Modul mit einem CP1202 Chipsatz von Silicon Labs. Einige dieser Module haben einen Layoutfehler: Der RST-Pin (9) ist fälschlicherweise mit 5V (VBUS) verbunden. Die Lösung ist diese Verbindung zu unterbrechen.