Ein Embedded-Board, eine JTAG-Schnittstelle und freie Software – mehr braucht man nicht für ein fertiges Entwicklungssystem für Embedded-Echtzeit-Linux. Dieses Tutorial zeigt Ihnen, wie das geht.
Das Installationsziel: Auf diesem Embedded-Board vom Typ pure.box 2 von Wiesemann & Theis wird das Embedded-Linux installiert und konfiguriert.
(Wiesemann & Theis)
Dieses Tutorial beschreibt, wie man von der Hardware in Form eines Embedded-Boards über JTAG (Joint Test Action Group) und den Bootloader U-Boot bis zum fertigen Embedded-Echtzeit-Linux-System kommt. Die hier vorgestellte Vorgehensweise wurde so allgemein wie möglich gehalten, um die Nachvollziehbarkeit und gegebenenfalls notwendige Abwandlungen durchführen zu können. Trotzdem wurde als Anschauungsobjekt ein konkretes Board gewählt. So kann der Leser bei Bedarf jeden einzelnen Schritt nachvollziehen.
Die erste Aufgabe besteht darin, eine Verbindung vom Entwicklungsrechner zum Zielsystem (Target) aufzubauen und damit zuerst den Bootloader zu installieren.
Dafür wurden die JTAG-Schnittstelle und darauf aufbauend OpenOCD (Open On-Chip-Debugger, im Netz unter der Adresse http://openocd.sourceforge.net/ zu finden) als Software gewählt. OpenOCD ist sowohl ein Daemon (also ein ohne User-Interface laufender Prozess) als auch die ausführende Einheit im Zusammenhang mit dem JTAG-Debugging. Bei der hier beschriebenen Vorgehensweise wird er als Interpreter von JTAG-Kommandos verwendet. Mit diesem Programm ist es deshalb möglich, den Bootloader zu debuggen und zu flashen.
Sobald der Bootloader läuft, hat man bereits Software, mit der man kommunizieren kann und die es erlaubt, den Rest des Systems aufzubauen. Der Bootloader namens U-Boot übernimmt das Starten eines provisorischen Linux-Kernels mit einer RAM-Disk sowie das Flashen des Kernels. Das Root-Filesystem wird hier durch den intermediären Kernel per RAM-Disk erstellt.
Die Beispiele in diesem Artikel beziehen sich auf ein Board von Wiesemann und Theis (pure.box2) mit einer ARM-Marvell-CPU. Es verfügt über ein Standard-ARM-JTAG-Interface, 1 Gigabyte NAND-Flash, eine serielle Schnittstelle sowie Ethernet und weitere Peripherie. Das JTAG-Interface wird mit einem JTAG-Adapter von Olimex an den USB-Port des Entwicklungsrechners angeschlossen.
Der dafür eingesetzte Chip ist der weit verbreitete Mikrocontroller FTDI-2232. Zwischen dem Board und dem verwendeten JTAG-Adapter ist ein Flachbandkabel mit einer 26-poligen zweireihigen Buchsenleiste (2,54 mm) auf eine 20-polige Steckerleiste (2,00 mm) notwendig, das sich einfach herstellen lässt. Die PIN-Belegung entspricht dem ARM-Standard und muss nicht geändert werden.
Gezielt entwickelt: Schema des Targetings des Zielsystems vom Testrechner aus
(IT-Klinger)
Die JTAG-Verbindung zum Zielsystem aufbauen
Auf Seiten des Entwicklungsrechners muss die USB-Seite des JTAG-Adapters angesprochen werden können. Dafür wird OpenOCD verwendet. Dieser Dämon kommuniziert mit dem JTAG-Adapter auf der einen Seite und bietet auf der anderen Seite folgende Server-Socket-Schnittstellen als Interface:
Terminal (Port 4444) – Interaktive Schnittstelle zur Verwendung von JTAG
Debugger (Port 3333) – Schnittstelle mit mi-Protokoll zur Verwendung durch den GNU-Debugger gdb.
Die JTAG-Verbindung zum Zielsystem erfolgt von OpenOCD über den USB-Treiber für FTDI-Chips namens libftdi zum JTAG-Adapter. Dieser steht unter der Adresse http://www.intra2net.com/en/developer/libftdi/download.php im Netz.
Zwingende Voraussetzung für libftdi ist die Bibliothek libusb für den systemübergreifenden USB-Zugriff, die zuerst installiert sein muss. Danach kann die Treiberbibliothek libftdi aus dem Internet geladen und installiert werden:
cd /home/linux/inst-wut
tar -xvzf libftdi-0.19.tar.gz
cd libftdi-0.19
./configure --prefix=/usr
make
make install
Anschließend wird der Open On-Chip-Debugger OpenOCD aus dem GIT-Repository geholt, erstellt und mit dem folgenden Skript installiert:
cd /home/linux/inst-wut
git clone
git://openocd.git.sourceforge.net/
gitroot/openocd/openocd
cd openocd
./bootstrap
./configure --enable-maintainer-mode
--enable-ft2232_libftdi
--prefix=/usr
make
make install
Übersetzungsinstanz: Das Schaubild veranschaulicht die Funktion des Daemons OpenOCD
(IT-Klinger)
Die Konfiguration des Daemons OpenOCD ausführen
Die Installation von OpenOCD erfolgte im Verzeichnispfad /usr/share/openocd/. Im Unterverzeichnis scripts/board der OpenOCD-Installation befinden sich bereits vorgefertigte Skripte für eine ganze Reihe an Boards. Selbstverständlich wird man in aller Regel versuchen, ein vorhandenes Skript zu verwenden und dieses so zu modifizieren, dass es zum jeweils gerade verwendeten Board passt.
Zweckmäßig ist es, sich hierzu das entsprechende Skript ins Arbeitsverzeichnis unter dem Namen openocd.cfg zu kopieren, dann wird es als Default-Skript verwendet, z. B.:
cp /usr/share/openocd/scripts/
board/sheevaplug.cfg
/home/linux/inst-wut/openocd.cfg
In dem vorgefundenen und verwendeten Skript sind einige Anpassungen notwendig, zuvorderst:
CPU-Architektur (source cpu/...)
JTAG-Interface (source interface/...)
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel Communications Group GmbH & Co. KG, Max-Planckstr. 7-9, 97082 Würzburg einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von redaktionellen Newslettern nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung, Abschnitt Redaktionelle Newsletter.
JTAG-Geschwindigkeit (jtag_khz)
Notwendige Register-Einstellungen (mww ...) für boardspezifische Initialisierungen in der Prozedur sheevaplug_init(); diese wird in wut_init() umbenannt
OpenOCD installiert eine ausführliche Dokumentation, die beispielsweise mit der folgenden Zeile eingesehen werden kann:
info openocd
Auf der Homepage des Autors ist das angepasste Konfigurationsskript erhältlich.
Start und Verwendung des Daemons OpenOCD
Zur Verwendung von OpenOCD sind zwei bzw. drei Terminals notwendig:
Start des OpenOCD-Dämons in einem Terminal-Fenster
Verbindung mit dem Dämon zur Kommando-Eingabe als Socket-Client (netcat)
Verbindung des gdb mit dem Dämon zum Debuggen.
Der Dämon wird mit der folgenden Zeile gestartet:
openocd
Zur standardmäßigen Konfiguration wird die ins Arbeitsverzeichnis kopierte Datei openocd.cfg verwendet. Wenn sich der Dämon nicht beendet, dann ist eine Verbindung vorhanden. Erscheinen dagegen beim Start des Daemons Fehlermeldungen, dann kommen folgende typische Ursachen in Betracht:
Das falsche Device-ID vom Interface-Adapter (USB-JTAG-Umsetzer) wird erkannt;
Gegebenenfalls ist die JTAG-Geschwindigkeit zu hoch eingestellt (jtag_khz) ;
Oder es ist ein falscher Adapter-Typ angegeben (source interface/...);
Ein falscher oder unpassender CPU-Typ ist eingestellt (source cpu/...);
Die Bibliothek libftdi kann nicht benutzt werden;
Gegebenenfalls wird OpenOCD unter einem nicht privilegierten User ausgeführt (Tipp: User root verwenden);
Die JTAG-Belegung zwischen dem Adapter und dem Target passt nicht; als eventuelle Ursache kommt ein wackeliger Kontakt in Frage.
In einer weiteren Shell wird das Socket-Terminal-Programm netcat oder auch kurz nc gestartet:
netcat localhost 4444 oder
nc localhost 4444
Hier können Befehle von OpenOCD eingegeben oder auch eigene Prozeduren aus der Konfigurationsdatei aufgerufen werden. Zur Orientierung kann man einfach
> help
> help [Kommando]
eingeben und sich die Kurzbeschreibung der eingebauten Befehle anschauen.
Die OpenOCD-Konfiguration einrichten
Für die boardspezifischen Initialisierungen legt man sich zweckmäßig eine Prozedur in der Konfigurationsdatei openocd.cfg an. In dieser Datei werden das JTAG-Interface zurückgesetzt sowie die Register der CPU richtig eingestellt. Ein Beispiel dafür befindet sich in der Konfigurationsdatei sheevaplug.cfg als Prozedur sheevaplug_init. Wir verwenden diese Prozedur als Ausgangspunkt und nennen unsere wut_init.
Nach dem Start von OpenOCD können wir diese Prozedur im Kommando-Terminal direkt aufrufen: > wut_init
Den Bootloader können wir bei bestehender JTAG-Verbindung jetzt ganz einfach testen. Die Erstellung des Bootloaders wird im zweiten Teil des Tutorials beschrieben. Vom Entwicklungsrechner ins RAM auf dem Target kopieren wir ihn mittels:
> load_image /home/linux/u-boot/u-boot
Dieser Aufruf gibt die Adresse zurück, an die der Bootloader kopiert wurde. Nun können wir die Ausführung an der entsprechenden Adresse fortsetzen:
> resume 0x600000
Soll der Bootloader debugged werden, so wird einfach eine Instruktion an der betreffenden Adresse ausgeführt:
> step 0x600000
Die Ausführung hält an und man kann sich von einem anderen Terminal aus mit dem Debugger gdb verbinden. Die Ausgaben des Bootloaders sollten über eine serielle Schnittstelle sowie einer Terminal-Emulation sichtbar sein.
Debugging der JTAG-Verbindung
Zum JTAG-Debuggen mittels OpenOCD startet man ein eigenes Terminal und wechselt in das Verzeichnis des Bootloaders:
cd /home/linux/u-boot
Dort kann der Debugger aus der Cross-Development-Toolchain mit der folgenden Zeile gestartet werden:
arm-linux-gdb ./u-boot
Nun muss man sich mit dem Target verbinden. Als Übermittler fungiert hier der Daemon OpenOCD:
(gdb) target remote localhost:3333
Jetzt kann das Debuggen beginnen, beispielsweise folgendermaßen:
(gdb) b start_armboot Breakpoint
(gdb) c Continue --> Target läuft
(gdb) n Zeile überspringen
(gdb) s Hineinspringen
(gdb) p abc Variable ausgeben
...
Zum Testen des Bootloaders verbindet man sich durch ein serielles Nullmodemkabel mit dem Board und startet in einer weiteren, neuen Shell ein Terminalprogramm:
minicom -s
(Schnittstelle einstellen: 115,2k 8N1, kein Handshake)
Den Bootloader auf das Flash schreiben
Nachdem der Bootloader funktioniert und alle Probleme beseitigt sind, kann dieser persistent auf das Flash geschrieben, sprich geflashed werden. Dies erfolgt im Kommando-Terminal durch Initialisieren der Hardware, Erasen und Beschreiben des Flash:
> wut_init
> nand probe 0
> nand erase 0 0x0 0x100000
> nand write 0 /home/linux/u-boot.kwb
0x0 oob_softecc_kw
Im Kommandoterminal von OpenOCD startet man den Bootloader mit folgendem Befehl:
> resume
Wenn der Bootloader durchstartet, kann das JTAG-Interface vom Board getrennt und erneut gestartet werden.
* Andreas Klinger ist selbstständiger Diplom-Ingenieur (FH) und bietet Seminare zu Embedded- und Echtzeit-Linux an. Er ist außerdem beliebter Referent der Embedded Linux Woche. Kontakt: ak@it-klinger.de