Yocto:SDK:HD51

Aus TuxBoxWIKI
Version vom 30. September 2023, 19:43 Uhr von Dbt (Diskussion | Beiträge) (Kategorie entfernt)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Wie Neutrino-Images auf der Basis von Yocto OpenEmbedded erstellt werden, wurde bereits für Stlinux-basiernde Geräte beschrieben. Damit ist es generell möglich, mit bestimmten Linux-Grundkenntnissen, sein eigenes Image zu erzeugen, bzw. gibt Distributoren ein solides Werkzeug in die Hand, um Releases mit einer zuverlässigen Paktierung für Updates bereitzustellen und zu warten. Das Yocto-Build ist dafür quasi ein Standard und besitzt hierfür eine recht ausgereifte, gewartete und nachhaltig durchdachte Struktur. Für Entwickler ist es allerdings notwendig einen flexiblen Arbeitsbereich zu haben, um Applikationen zu entwickeln, zu warten und zu testen. Auch hierfür bietet Yocto passende Mittel. Dieser Artikel soll erklären, wie man eine solche Umgebung (SDK) aufsetzt und benutzt.

Vorbereitungen

Diese Anleitung wurde getestet mit OpenSuse 42.3. Für Debian basierende Distributionen sollten im wesentlichen die bereits hier genannten Schritte zur Vorbereitung zutreffend sein.

Stop hand.png HINWEIS:

Die hier verwendete Basis für die Erstellung einer Arbeitsumgebung basiert auf der Arbeit von Community-Mitgliedern. Auf Vollständigkeit, inhaltliche und rechtliche Korrektheit sowie Funktionsfähigkeit kann daher keine Garantie gegeben werden. Fehlerberichte, Meinungen und Vorschläge sollten daher an die Betreuer der jeweiligen Buildsysteme bzw. Layer gerichtet werden.

Pakete installieren

Für Debian basierte Systeme (getestet mit Wheezy und Jessie in 32/64bit).

$ sudo apt-get update
$ sudo apt-get install libsdl1.2-dev chrpath git build-essential automake texinfo

Für OpenSuse (getestet mit OpenSuse 42.3/15.0 64bit)

$ sudo zypper install git make gcc-g++ diffstat texinfo chrpath libSDL-devel python3-curses zip glew-devel freeglut-devel libid3tag-devel libmad-devel libogg-devel libsigc++2-devel flac-devel 
libvorbis-devel yasm

Bei Bedarf kann man weitere benötigte Pakete auch mit Hilfe der Suse Downloadsuche direkt nachinstallieren:

https://software.opensuse.org/search

Des Weiteren benötigt man ein extra Verzeichnis im $HOME in dem man alle nötigen Verzeichnisse samt zusätzlicher Unterverzeichnisse anlegen kann. Im folgenden wird $HOME/yocto verwendet, das kann natürlich jeder seinen Gepflogenheiten anpassen. Achtung, ein späteres Verschieben ist nicht einfach möglich da innerhalb der erzeugten Toolchain mit absoluten Pfaden gearbeitet wird!

$ mkdir ~/yocto && cd ~/yocto

Innerhalb dieses Verzeichnisses sollte man direkt auch einen gemeinsamen Downloadordner für die möglichen verschiedenen Systeme anlegen, dies erspart später mehrfaches Herunterladen der diversen Source Pakete. Wer ein entsprechendes Verzeichnis für derartige Downloads schon besitzt kann natürlich dieses auch per Symlink einbinden (oder in der späteren Konfiguration den entsprechenden Pfad angeben).

$ mkdir download

Benötigte locale Einstellungen

In Ausnahmefällen kann es zu solch einem Problem kommen:

Please use a locale setting which supports utf-8.
Python can't change the filesystem locale after loading so we need a utf-8 when python starts or things won't work.

In diesem Fall wird eine passende locale benötigt, die UTF8 unterstützt. Dabei kann man wie hier beschrieben vorgehen.

https://wiki.yoctoproject.org/wiki/TipsAndTricks/ResolvingLocaleIssues

SDK erzeugen

Eigenbau SDK

Hierbei wird quasi das komplette SDK mit Bitbake selbst erzeugt und anschließend das erzeugte SDK installiert. Im Gegensatz zu einem einfachen Download sind hier mehrere Schritte notwendig. Dies nimmt natürlich mehr Zeit in Anspruch, weil beim Bauen des SDK deutlich mehr Targets gebaut müssen.

Schritt 1: Benötigte Repos klonen

Stop hand.png Wichtig: Bemerkung zur Versionierung und den benötigten Yocto und Meta-Layer-Versionen.:

Im Yocto-Projekt haben die verschiedenen Entwicklungstände wechselnde Projekt- bzw. Releasenamen. Solche Projektnamen wären z. B. krogoth, sumo, thud usw. und hinter diesen Aliasses befinden sich im Yocto Repository auch übliche numerische Revisionen. Sumo entspräche zB. 2.5.x, Thud 2.6.x usw.

Diese Versionsstände bzw. Aliasse definieren zwingend die benötigten Versionen der Meta-Layer meta-neutrino und meta-hd51. Diese Versionen sind daher parallel als Branch in den jeweiligen Repositories vorhanden und müssen mit denen aus dem Yocto-Repository übereinstimmen, um ein fehlerfreies Bauen zu ermöglichen. Diese Stände werden so auch in das System unseres Images als Releaszyklus durchgereicht. Unter Neutrino kann man das auch über die Ausgabe der Informationen entsprechend abrufen.

Klonen des Yocto Poky Projektes in den Buildsystemordner

 $ git clone git://git.yoctoproject.org/poky.git poky
 Klone nach 'poky' ...
 remote: Counting objects: 412580, done.
 remote: Compressing objects: 100% (97765/97765), done.
 remote: Total 412580 (delta 308026), reused 412408 (delta 307854)
 Empfange Objekte: 100% (412580/412580), 149.51 MiB | 316.00 KiB/s, Fertig.
 Löse Unterschiede auf: 100% (308026/308026), Fertig.

In das geklonte Repository wechseln:

 $ cd poky

In den benötigen Branch wechseln. Welcher Branch benötigt wird, hängt vom jeweiligen Stand ab (in diesem Bespiel "sumo"). siehe Anmerkung oben! Dieses Beispiel zeigt wie man für den 'sumo-Branch' vorgeht. Normalerweise sollte immer der letzte Stand genommen werden, jedoch nicht der 'master'. Dafür holen wir uns diesen noch ab und wechseln auf den benötigten Branch:

 $ git checkout -b sumo  origin/sumo
 Branch sumo konfiguriert zum Folgen von Remote-Branch sumo von origin.
 Zu neuem Branch 'sumo' gewechselt

Klonen der Meta-Layer-Repos für Neutrino und der jeweiligen Plattform in den poky-Ordner

In diesem Fall wird als Beispiel die AX/Mut@nt HD51 Plattform verwendet. Wir benötigen auch hier den dafür erforderlichen Branch. siehe Anmerkung oben! Dieses Beispiel zeigt wie man für den 'sumo-Branch' vorgeht, jedoch sollte immer der aktuell gewartete Stand genommen werden, aber nicht der 'master'. Dafür holen wir uns diesen noch ab und wechseln auf den benötigten Branch:

 $ git clone https://github.com/neutrino-hd/meta-hd51.git

Sollte der benötigte Branch im Remote-Repository bereits als Standard eingerichtet sein, also wie hier 'sumo', sind die drei nächsten Befehle nicht nötig. Führt man diese trotzdem aus, wird dies mit einer Fehlerausgabe quittiert, die besagt, dass der Branch bereits vorhanden ist, was man getrost ignorieren kann.

 $ cd meta-hd51
 $ git checkout -b sumo  origin/sumo
 Branch sumo konfiguriert zum Folgen von Remote-Branch sumo von origin.
 Zu neuem Branch 'sumo' gewechselt
 $ cd ..

Klonen des benötigten neutrino meta-Layers:

 $ git clone https://github.com/neutrino-hd/meta-neutrino.git

Sollte auch hier der benötigte Branch im Remote-Repository bereits als Standard eingerichtet sein, sind die drei nächsten Befehle nicht nötig. Mann muss aber sicherstellen, dass man sich zum Schluß im 'poky'-Ordner befindet.

 $ cd meta-neutrino
 $ git checkout -b sumo  origin/sumo
 Branch sumo konfiguriert zum Folgen von Remote-Branch sumo von origin.
 Zu neuem Branch 'sumo' gewechselt
 $ cd ..

Schritt 2: Umgebung einrichten

Zuweisen der Vorlage für die Beispielkonfiguration

 $ export TEMPLATECONF=meta-hd51/example_neutrino

Umgebung für "build-hd51" mittels dem "Environment Skript" erzeugen

Es werden dabei automatisch die benötigten Umgebungsvariablen und ein Buildordner erzeugt und in diesen gewechselt

 $ . ./oe-init-build-env build-sdk-hd51

Schritt 3: Anpassen der Konfiguartion

  • mit einem Editor deiner Wahl, die Konfiguration bearbeiten
 $ kate conf/local.conf

Falls gewünscht, einen Downloadordner bestimmen. Dieser wird standardmäßig im Yocto-Ordner als yocto/download angelegt. Man kann auch einen Link auf einen bereits vorhandenen Ordner setzen, was durchaus Sinn macht, denn die Downloads dürften sehr umfangreich sein. Ein vorhandenes Archiv kann sich daher als vorteilhaft erweisen.

   DL_DIR = "/path/to/your/archiv"
  • Hosttyp zuweisen, auf dem dieses SDK lokal verwendet werden soll. Hier als Beispiel x86_64:
   #SDKMACHINE ?= "i686"
   SDKMACHINE ?= "x86_64"
   #SDK_LOCAL_CONF_WHITELIST = "SSTATE_MIRRORS"
   SDK_INCLUDE_PKGDATA = "0"
   #SSTATE_MIRRORS = "file://.* http://my.server.com/path/to/sstate-cache/PATH"
   
  • Entwicklung am Tuxbox-Neutrino erfordert diesen Eintrag, dies ist auch der Standard:
   FLAVOUR ="mp"
  • Je nachdem was die Hostmaschine verträgt, kann man hier die Anzahl der Threads und Parallel-Makes angeben.
   # Determine how many tasks bitbake should run in parallel:
   BB_NUMBER_THREADS ?= "4"
   # Determine how many processes make should run in parallel when running compile tasks:
   PARALLEL_MAKE ?= "-j 4"

DIESE EINSTELLUNG MUSS BLEIBEN!

  # What image to build ?
  IMAGENAME = "neutrino-image"
  • um mögliche Prüfsummenfehler zu vermeiden kann es erforderlich sein, diese Einträge auszukommentieren:
#UNINATIVE_CHECKSUM[x86_64]
#SSTATE_MIRRORS += " file://universal/(.*) file://universal-4.9/\1 file://universal-4.9/(.*) file://universal-4.8/\1"

Die anderen Einstellungen sollten sich von selbst ergeben.

Variablen ermitteln

Um alle Build- bzw. Umgebungsvariablen abzufragen, diesen Befehl eingeben:

bitbake -e

Dies wird natürlich eine sehr große Ausgabe ergeben, in der man sich durch alle Variablen durchscrollen kann. Um gezielt eine Variable zu ermitteln, kann dies z.B. grep vornhemen. In diesem Beispiel wird WORKDIR ermittelt.

bitbake -e (recipe) | grep ^WORKDIR=

Auf diese Weise kann z.B. man testen, welche Variable mit welchem Wert bestückt wurde.

Schritt 4: SDK bauen

Der normale Befehl, um ein Image zu bauen lautet:

 $ bitbake neutrino-image

Dies ist für den normalen Gebrauch völlig ausreichend und kann zur Distribution verwendet werden. Auch devtool würde damit bereits funktionieren und ein separater "Workspace" zum Entwickeln kann angelegt und verwendet werden. Die wichtigsten Pakete müssten damit erzeugt worden sein, die als Updatequelle bereitgestellt werden könnten. Zusammen mit dem Image sollte man auch die Paketdaten der einzelnen Pakete erzeugen, welche später als Metadaten der Updatequellen für den Paketmanager (OPKG) Verwendung finden. Sollte ein neues Image oder einzelne Pakete aktualisiert und gebaut worden sein, kann man diese Metadaten jederzeit aktualisieren:

$ bitbake package-index

Um nun ein SDK zu bauen, folgendes ausführen:

 $ bitbake -c populate_sdk_ext neutrino-image

Dabei werden jede Menge zusätzliche Tasks zum Erzeugen der SDK-Pakete ausgeführt. Wenn alles glattgeht, sind neben den Standardpaketen, Images usw. die unter tmp/deploy abgelegt werden nun auch die SDK-Pakete abgelegt. Das gewünschte Installationsskript für das SDK ist hier zu finden:

tmp/deploy/sdk/oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-nodistro.0.sh

Falls notwendig, das Installationsscript noch ausführbar machen:

  $ chmod 755 oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-nodistro.0.sh

SDK installieren

Je nachdem ob das Installationsskript frisch erzeugt wurde oder wie hier beschrieben heruntergeladen wurde, jetzt in das Verzeichnis wechseln, in dem sich das Skript befindet.

Installationsscript ausführen und den Anweisungen folgen.

Einige Eingaben können leer bleiben, um Standardwerte setzen zu lassen. Falls nötig, ist sudo erforderlich. Das Zielverzeichnis sollte man aber an einer für sich günstigen Stelle setzen, also möglichst schon etwas voraus planen.

 $ cd <Pfad/zum/Installations-Skript-Ordner>
 $ ./oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-nodistro.0.sh
    OpenEmbedded SDK installer version nodistro.0
    =============================================
    Enter target directory for SDK (default: /home/<USER<>/sdk):
    You are about to install the SDK to "/home/<USER<>/sdk". Proceed[Y/n]? y
    Extracting SDK......................................................................................done
    Setting it up...done
    SDK has been successfully set up and is ready to be used.
    Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
    ...

Nach der Installation, sollte in etwa diese Struktur vorhanden sein:

 $ your@hostname:~/yocto/poky/build-sdk-hd51/tmp/deploy/sdk$ tree -L 4 /home/<USER<>/sdk
   /home/<USER>/sdk
   ├── environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi  <- Das ist das SDK environment script 
   ├── site-config-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
   ├── sysroots
   │   ├── cortexa15hf-neon-vfpv4-oe-linux-gnueabi
   .
   .
   .
   └── version-cortexa15hf-neon-vfpv4-oe-linux-gnueabi


SDK Umgebung erzeugen

In das frisch erzeugte SDK-Verzeichnis wechseln

 $ /home/<USER>/sdk

Environment Script ausführbar machen (falls erfordelich)

$ chmod 755 environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi 

Um zu testen, wie die aktuelle Umgebung eingerichtet ist, kann man die $PATH Variable ausgeben lassen. Ohne das ausgeführte Skript würde das etwa so aussehen:

 $ echo $PATH
 $ /home/<USER>/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin

Environment Script ausführen

 $ . ./environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi

Was ist passiert? Das Skript sollte nun die Umgebung angepasst haben und man kann erahnen, worauf das Ganze hinausläuft.

 $ echo $PATH
 $ /home/<USER>/devel/sdk/hd51/sysroots/x86_64-oesdk-linux/usr/bin:/home/<USER>/devel/sdk/hd51/buildtools/sysroots/x86_64-oesdk-linux/usr/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/sbin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/sbin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin/../x86_64-oesdk-linux/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin/arm-oe-linux-gnueabi:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin/arm-oe-linux-musl:/home/<USER>/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin
Stop hand.png HINWEIS:

Immer wenn man das SDK nutzen möchte und dafür eine neue Shell-Sitzung geöffnet hat, muss dieses Environment-Skript ausgeführt werden. Die Umgebung bleibt dann solange erhalten, bis diese Sitzung geschlossen wird!


Umgebungsvariablen

Neben der bereits angepassten $PATH-Umgebung, sind nun auch einige weitere Umgebungsvariablen verfügbar:

SDKTARGETSYSROOT - The path to the sysroot used for cross-compilation
PKG_CONFIG_PATH - The path to the target pkg-config files
CONFIG_SITE - A GNU autoconf site file preconfigured for the target
CC - The minimal command and arguments to run the C compiler
CXX - The minimal command and arguments to run the C++ compiler
CPP - The minimal command and arguments to run the C preprocessor
AS - The minimal command and arguments to run the assembler
LD - The minimal command and arguments to run the linker
GDB - The minimal command and arguments to run the GNU Debugger
STRIP - The minimal command and arguments to run 'strip', which strips symbols
RANLIB - The minimal command and arguments to run 'ranlib
OBJCOPY - The minimal command and arguments to run 'objcopy
OBJDUMP - The minimal command and arguments to run 'objdump
AR - The minimal command and arguments to run 'ar
NM - The minimal command and arguments to run 'nm
TARGET_PREFIX - The toolchain binary prefix for the target tools
CROSS_COMPILE - The toolchain binary prefix for the target tools
CONFIGURE_FLAGS - The minimal arguments for GNU configure
CFLAGS - Suggested C flags
CXXFLAGS - Suggested C++ flags
LDFLAGS - Suggested linker flags when you use CC to link
CPPFLAGS - Suggested preprocessor flags


SDK verwenden

Umgebung direkt nutzen

Quellcodedateien könnten praktisch damit bereits direkt kompiliert werden. Auch IDE's könnten damit eingerichtet werden. Befände man sich in dieser Umgebung, würde z.B. dieses Kommando ein Programm für die gewünschte Plattform erzeugen:

$ $CC main.cpp -o test

Auf Basis dieser angepassten Umgebung könnten bereits vorhandene Makfiles oder ganze Buildsysteme angepasst werden. Dabei müssten diese Umgebungsvariablen an das Buildsystem durchgereicht werden. Dies kann je nach Aufbau der Makefiles oder der Buildsystemstruktur sogar bereits funktionieren. Gut durchdachte Systeme sollten das durchaus ermöglichen, andernfalls kann es auch einen gewissen Aufwand bedeuten.


Arbeiten mit devtool

Wie bereits erwähnt, bietet das Yocto-Buildsystem Lösungen an, um gezielt an (fast) jeder beliebigen Applikation, welche im Buildsystem übersetzt wird, zu arbeiten. Parallel zu bitbake, was allgemein verwendet wird, steht auch ein speziell zugeschnittenes Script namens devtool zur Verfügung, dass für die Aufgaben im Workspace ausgelegt ist. Dieses Script setzt zwar auf Bitbake auf, stellt aber zusätzliche Kommandos für die Entwicklung an einzelnen Applikationen oder der Recipes selbst bereit. Die üblichen Bitbake-Kommandos stehen in der reinen SDK Umgebung allerdings nicht zur Verfügung.


Vorbereitung

Konfiguration anpassen

Die Konfiguration des SDK befindet sich nun im SDK-Ordner unter:

sdk-hd51/conf/local.conf

Im Wesentlichen wurde die ursprüngliche Konfiguration des Buildsystems in die SDK-Konfiguration übernommen, jedoch sollte man dies zumindest nachprüfen und wenn nötig einige Anpassungen vornehmen, die den lokalen Gegebenheiten entsprechen. Wurde das SDK mit dem heruntergeladenen Installationsskript erzeugt, sollte man dies auf jeden Fall tun, da hier bestimmmte Einstellungen des Verteilers noch vorhanden sind und mit Sicherheit nicht zutreffen. Wenn alles passt, weiter mit dem nächsten Schritt.


Image bauen

$ devtool build-image

Das dauert eine Weile. Der Befehl vermittelt zwar nur, das ein lauffähiges Image erstellt wird, aber dieses Kommando sorgt auch dafür, dass alle zugehörigen Pakete erstellt werden und eine abgewandelte Version des Buildsystems samt benötigter Entwicklungsumgebung erzeugt wird. Dieser Vorgang ist daher zu Beginn zwingend notwendig, damit die Arbeitsgrundlage für das weitere Arbeiten an den Sourcen überhaupt erst hergestellt wird.

Nachdem der Vorgang abgeschlossen ist, sollte das fertig gebaute Image hier zu finden sein:

/home/<USER>/<PATH/TO/YOUR/SDK>/
|...
.
.
├── tmp
│   ├── deploy
│   │   ├── images
           └── ...

Dort werden mehrere Typen von Images abgelegt, die je nach Bedarf bzw. Hardwarevoraussetzung mit bestimmten Vorgehensweisen geflasht werden können.

Image flashen

Nachdem erfolgreich Images und Pakete erzeugt wurden, möchte man nun das Ganze auch benutzen. Dafür muss natürlich das Ergebnis auf die Zielhardware gebracht werden, indem man das erzeugte Image flasht. Anschließend ist die Hardware damit nutzbar und auch die deploy-target Methoden können zum Entwickeln zusammen mit Devtool verwendet werden.


Methode: E2

Für diese Methode wird die E2 Benutzeroberfläche verwendet, sofern diese (noch) installiert ist. In fabrikneuem Zustand sollte dies immer der Fall sein. E2 bietet dann auch die Möglichkeit, die gewünschte Start-Partition zu setzen.

Statt ein E2-Image muss logischerweise ein frisch erzeugtes Neutrino-Image genommen werden. Dafür ein Image aus ../tmp/deploy/images/hd51 holen! Neutrino-Images sind unter https://update.tuxbox-neutrino.org/dist/hd51/3.0.3/images zu finden. Die benötige Imagedatei hat die Kennung: ..._ofgwrite.zip.

Für diese Vorgehensweise sei auf die Anleitungen bei OpenATV verwiesen.


Methode: USB-Stick

Achtung: Manche Sticks sind nicht geeignet, daher kann es notwendig sein, verschiedene Modelle zu probieren. Mit dem hier abgebildetem Stick, wurde der Vorgang erfolgreich durchgeführt.

Cruzer Blade 16GB

Eine fabrikneue AX HD51/Mut@nt wird in der Regel mit E2 ausgeliefert und ist zudem multibootfähig. Der Flashspeicher ist daher recht üppig ausgestattet und bietet die Möglichkeit insgesamt 4 Partitionen mit jeweils einem Image zu bestücken, welches je nach Einstellung verwendet werden kann.

Flashen mit Hilfe eines USB-Sticks ist die gebräuchlichste Methode. Arbeitsschritte über GUI, serieller oder Shell-Zugang zur Box sind nicht notwendig.

Stop hand.png HINWEIS:

Diese Methode hat den Nachteil, dass zuvor bereits installierte Systeme nicht mehr verwendet werden können. Wer sich nicht daran stört, alle Informationen im emmc Speicher zu verlieren und eventuelle Multiboot Images unbrauchbar werden, kann diese Methode getrost verwenden.

Vor dem Flashen andere USB-Geräte wie Sticks oder Festplatten vom Gerät trennen!

  1. USB Stick mit mindestens 2 GB Speicher und formatiert mit FAT32 am PC vorbereiten.
  2. Image aus ../tmp/deploy/images/hd51 holen! Das Zip-File hat die Kennung: ..._usb.zip wobei das aktuellste immer ohne Zeitstempel beschriftet ist. Die restlichen ohne USB-Kennung werden für andere Methoden benötigt.
  3. Zip File entpacken und Ordner hd51 vollständig auf den USB Stick kopieren.
  4. Box vom Strom trennen
  5. USB-Stick an den Front-USB-Port einstecken.
  6. Power-Taste an der Frontseite gedrückt halten und Box unter Strom setzen.
  7. Sobald Flashing im Display erscheint, die Power-Taste loslassen.
  8. Nach erfolgreichem Flashen startet die Box automatisch.
Methode: Terminal

Diese Methode funktioniert nur, wenn bereits ein Neutrino-Image installiert wurde.

Benötigt wird ein Image aus ../tmp/deploy/images/hd51 mit der Bezeichnung:

neutrino-image-flash.zip

Image entpacken und den entpackten Ordner hd51 vollständig an einen Ort hochladen, wo genug Platz ist. Das Image ist gepackt ca. 100 MB bzw. entpackt ca. 800 MB groß. Ein USB-Stick würde sich beispielsweise anbieten.

Angenommen diese Datei wurde hier hin hochgeladen:

/media/USB/hd51

Auf die Box einloggen:

ssh root@hd51
.
.
.
 __  __         __         ___       __
 \ \/ /__  ____/ /____    / _ \___  / /____ __
  \  / _ \/ __/ __/ _ \  / ___/ _ \/  ´_/ // /
  /_/\___/\__/\__/\___/ /_/   \___/_/\_\\_, /
                                       /___/

Neutrino-HD image (based on Yocto tuxbox sumo)hd51 ttyS0

hd51 login: root
➜  ~


Kommando zum Flashen eingeben. Zu beachten wären die Parameter.

  • 2 bedeuted, dass das Image in die 2. Partition geschrieben wird.
  • /media/USB/hd51 gibt den Ordner an, in dem sich das Image befindet.


➜  ~ flash 2 /media/USB/hd51

Das dauert jetzt einen Moment:

Writing image into partition 2

Writing kernel into /dev/mmcblk0p4
4.55MiB 0:00:00 [11.9MiB/s] [================================>] 100%

Writing rootfs into /dev/mmcblk0p5
800MiB 0:01:28 [9.08MiB/s] [================================>] 100%

Flash successful

Dieser Vorgang dauert etwas. Nachdem dieser Vorgang erfolgreich abgeschlossen wurde, bootet die Box automatisch neu. Sollte vor dem Flashen bereits ein USB-Stick (hinten USB2-Port) oder eine Festplatte verbaut oder angeschlossen gewesen sein, sollten auch die alten Einstellungen wieder vorhanden sein.


Methode: Terminal: mit ofgwrite

Diese Methode funktioniert, mit bereits installierten Neutrino-Image und mit Boxen auf denen noch ein werkseitig installiertes E2-Image (z.B. Open ATV) installiert ist.

Stop hand.png HINWEIS: auf diese Art und Weise kann nicht in die momentan verwendete Partition geschrieben werden und es erfolgt keine Sicherung von Daten und Einstellungen!

Benötigt wird ein Image vom Update-Server oder ein selbst gebautes aus ../tmp/deploy/images/<box> mit dem Suffix:

..._ofgwrite.zip

Zip-Datei entpacken. Danach sollte diese Dateien vorhanden sein:

ls -lgo
insgesamt 134188
-rw-r--r-- 1        33 Okt  7 22:07 imageversion
-rw-r--r-- 1   4774184 Okt  7 22:07 kernel.bin
-rw-r--r-- 1 132623427 Okt  7 22:07 rootfs.tar.bz2

Den entpackten Ordner am besten vollständig an einen Ort hochladen, wo genug Platz ist. Ein USB-Stick würde sich beispielsweise anbieten.

Angenommen die drei entpackten Dateien wurden in diesen Ordner hochgeladen:

/media/hdd1

Auf die Box einloggen:

ssh root@hd51
login as: root
Pre-authentication banner message from server:
|  __  __         __         ___       __
|  \ \/ /__  ____/ /____    / _ \___  / /____ __
|   \  / _ \/ __/ __/ _ \  / ___/ _ \/  '_/ // /
|   /_/\___/\__/\__/\___/ /_/   \___/_/\_\\_, /
|                                        /___/
|
| welcome to hd51 neutrino-hd image
End of banner message from server
root@hd51's password:
➜  ~

Kommando zum Flashen eingeben. Zu beachten wären die Parameter.

  • 2 bedeuted, dass das Image in die 2. Partition geschrieben wird.
  • /media/hdd1 gibt den Ordner an, in dem sich die entpackten Dateien befinden.
➜  ~ofgwrite -m2 /media/hdd1

Am Bildschirm wird jetzt der Fortschritt angezeigt. Dieser Vorgang dauert etwas. Nachdem dieser Vorgang erfolgreich abgeschlossen wurde, bootet die Box automatisch neu.

Um auch von der soeben geflashten zweiten Partition starten zu können, muss noch ein Befehl gegeben werden:

cp /boot/STARTUP_LINUX_2 /boot/STARTUP

Je nach Partitionslayout kann es vorkommen, dass diese Dateien anders benannt sind und daher z.B. /boot/STARTUP_LINUX_2 nicht gefunden wurde, kann diese Ausgabe erscheinen:

cp: can't stat '/boot/STARTUP_LINUX_2': No such file or directory

Dann kann man das hier versuchen bzw. im /boot Verzeichnis nachschauen, wie die Dateien benannt sind und den Befehl entsprechend anpassen:

cp /boot/STARTUP_2 /boot/STARTUP

Box neu booten:

reboot


Methode: Online

Diese Methode ermöglicht ein Online-Image zu flashen bei dem ein Image direkt vom Update-Server geladen werden kann. Voraussetzung ist hier ein bereits installiertes Yocto-Image. Auch die GUI nutzt diese Methode. Zu finden ist das Online-Update im Sevice-Menü unter dem Menüeintrag Imageverwaltung. Auf einem anderen Server abgelegte Images lassen sich mit dieser Methode nur bedingt, also nicht ohne manuelle Eingriffe an den zuständigen Skripten verwenden. Dazu muss in mehreren Skripten die Update-Adresse geändert werden.

Die Syntax zum flashen mittels Terminal lautet:

systemctl start flash@<PARTITION-NUMMER>

oder

flash <PARTITION-NUMMER>

Um ein Online-Update zu erwingen:

flash <PARTITION-NUMMER> force

Um z.B. ein Image in die erste Partition zu schreiben, wird dieser Aufruf benötigt:

 systemctl start flash@1

Nach erfolgreichem Flashen, bootet die Box neu.


Methode: GUI

Diese Methode ermöglicht das Flashen direkt über die Benutzeroberfläche. Voraussetzung ist hier ein bereits installiertes Neutrino-Image, auf dem die benötigeten Erweiterungen installiert sind. Zu finden ist die Funktion im Sevice-Menü unter dem Menüeintrag Imageverwaltung.

Flashen via Imageverwaltung


Die Menüeinträge sind quasi selbsterklärend. Je nach Vorgehensweise kann man hier die Updatemethode auswählen.

Flashen via Imageverwaltung

Nach erfolgreichem Flashen, bootet die Box neu.


Arbeitsbereich einrichten

Devtool hat nun quasi ein modifiziertes Duplikat des Buildsystems erstellt. Wie schon bemerkt wurde, ist das "normale" Yocto-Buildsystem, mehr für den Bedarf von Distributoren vorgesehen. Man kann daher mit Bitbake selbst nur begrenzt arbeiten. Die Arbeit am Quellcode dürfte daher im Vergleich zu gewohnten Buildsystemen teilweise recht träge verlaufen.

Mit dem SDK bzw. mit devtool werden flexiblere Möglichkeiten angeboten. Es kann z.B. jedes Paket im Workspace abgelegt werden, um daran zu arbeiten, erzeugte Pakete können sofort auf die Zielhardware geladen und getestet werden. Weiterhin wird nicht immer generell ein Paket bei jedem angestoßenem Buildvorgang komplett neu gebaut, sondern mit bestimmten Kommandos nur das, was notwendig ist. Auch bei Abbrüchen wird immer dort fortgesetzt, wo dieser Abbruch statt fand. Das ist wesentlich handlicher und entspricht etwa dem Ablauf, den man von bisherigen Buildsystemen oder beim Ausführen von Make her kennt. Außerdem lassen sich mit Receipes mit Hilfe von Templates anlegen um nur einige Details zu nennen.

Eine Echtzeitverfolgung der Makevorgänge wird standardmäßig zwar nicht angezeigt, aber dafür werden bei Build-Abbrüchen standesgemäß sofort entsprechende Ausgaben angezeigt, die mögliche Fehler sofort erkennen lassen. Ein dauerhaftes und ausführliches Logging mit Anzeige wo diese Logs im Falle von Build-Fehlern zu finden sind, ermöglicht zudem eine genaue Durchsicht aller gemachten Vorgänge und zwar getrennt nach Konfigurierung, Kompilierung, Paketierung usw.

Die Imageerstellung erfolgt konform zum normalem Bauen mit Bitbake. Änderungen an Quellcodes werden normalerweise direkt übernommen. Der dafür notwendige Befehl

devtool build-image

wurde ja schon erwähnt.

Auch die Layer befinden sich in der neu erstellten Struktur und können dort gewartet werden. Diese befinden sich allerdings quasi in reinem Quellzustand, also ohne Anbindung an eine Versionsverwaltung. Dies kann man aber selbst nachholen, indem man die betreffenden Layer nur durch die GIT-Repositories ersetzt. Man klont nur einfach die Git-Repositories an deren Stelle.

├── hd51
│   ├── bitbake-cookerdaemon.log
│   ├── buildtools
...

│   ├── cache
...
│   ├── conf
...
│   ├── downloads
...
│   ├── environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
│   ├── layers
│   ├── site-config-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
│   ├── sstate-cache
...
│   └── 'workspace'
│       ├── appends
│       ├── conf
│       ├── README
│       └── 'sources'
└── oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh
...

Quelldaten importieren

Wie man sieht, gibt es nun ein "workspace"-Verzeichnis, welches einen Unterordner namens "sources" beinhaltet. Darin befinden sich normalerweise die Quelldaten der Applikationen an denen gearbeitet wird. Dieser Bereich ist noch leer und muss noch befüllt werden. Erwähnt sei noch, dass es ratsam ist, wie im Falle von Neutrino, auch die dazu gehörige libstb-hal einzupflegen, da diese dann auch zusammen bearbeitet werden können und so sichergestellt ist, immer zusammen mit dem bearbeiteten Stand im Workspace kompiliert zu werden. Wenn man z.B. an Neutrino arbeiten möchte, folgendes eingeben:

$ devtool modify neutrino-mp
$ devtool modify libstb-hal

Devtool wird den zugehörigen Quellcode, der in der Regel als GIT-Repository vorliegt, in den Workspace-Ordner "umsiedeln".

Den Status des Arbeitsbereiches, also welche Applikationen derzeit in Verwendung sind, kann man so abfragen:

$ devtool status  


Entwickeln

Quelldaten ändern

In den jeweiligen Git-Repos, kann man jetzt seine Änderungen am Quellcode wie gewohnt vornehmen und neu kompileren.

...
│   └── workspace
...
│       └── sources
│           └── 'neutrino-mp'
...


Neutrino kompilieren

$ devtool build neutrino-mp

Wie dieser Befehl schon vom Namen her sagt, wird damit Neutrino einschließlich aller Abhängigkeiten gebaut bzw. die dazugehörigen Pakete erzeugt. Das Ergebnis muss aber erst noch zum Testen auf die Zielhardware geladen werden.


Neutrino auf Ziel-Hardware laden

$ devtool deploy-target -s neutrino-mp root@<BOX-IP>

oder auch kombiniert:

$ devtool build neutrino-mp && devtool deploy-target -s neutrino-mp root@<BOX-IP> 

Alle benötigten Daten, welche in entsprechenden Paketen enthalten sind, werden damit via SSH auf die Zielhardware geladen. Die Option -s bewirkt, dass man verfolgen kann, welche Daten gerade hochgeladen werden. Anschließend kann man direkt auf der Hardware testen.

Stop hand.png HINWEIS:

Für Binaries sei noch zu beachten, dass diese standardmäßig ungestrippt hochgeladen werden. Das bedeutet, das man unter Umständen längere Ladezeiten in Kauf nehmen muss und genügend Speicherplatz auf der Zielhardware einplanen sollte. Vorausgesetzt, man benötigt keine ungestrippten Daten, hilft die Option -S, um nur gestrippt Binaries hochzuladen:

$ devtool deploy-target -s -S neutrino-mp root@<BOX-IP>

Die Option -S gibt es aber unglücklicherweise erst in neueren Yocto-Versionen. Derzeit werden für die CST- und Fulan-Geräte (Spark etc.) aber eben keine aktuellen Versionen (z.Z. nur krogoth) verwendet und eine Portierung ist auch nicht in Aussicht, da die neueren Versionen unter anderem keinen Support mehr für die veralteten Kernel und uclibc-Support leisten. Zudem stellen die closed-Source Treiber ein Problem dar, die mit den neuen Yocto-Images nicht kompatibel sein dürften.

Für Geräte wie die AX51 sind die Ladezeiten allerdings zu vernachlässigen und Speicher ist normalerweise auch großzügig vorhanden. Bei CST Hardware sollte man daher wegen des knappen Speichers nur mit einem möglichst schnellem USB-Stick arbeiten und nicht den Flash nutzen. Bei den CST-HD2 Serien ist die Ladezeit zwar noch moderat, aber wegen unterschiedlicher Flashbestückung der einzelenen HD2 Modelle, sollte man auch hier genau auf die Speichergrößen achten!


Stop hand.png TIP: devtool deploy-target nutzt Zugriff via SSH auf die Box und es wäre daher recht unpraktisch, immer wieder nach einem Passwort gefragt zu werden. Um dies abzustellen kann man sich auf der Zielhardware via SSH einloggen und das Passwort entfernen:

 ~$ passwd -d root


Neutrino von Ziel-Hardware entfernen

$ devtool undeploy-target neutrino-mp root@<BOX-IP>

Dies entfernt die devtool-Modifikationen auf der Zielhardware und stellt den ursprünglichen Zustand auf der Zielhardware wieder her.


Aktuelles Image erzeugen

$ devtool build-image


An einem beliebigem Paket entwickeln

Man kann quasi jedes Paket aus dem Buildsystem separat bearbeiten, debuggen und selbst daran entwickeln. Wie weiter oben schon wie für Neutrino angedeutet wurde, wird dafür der gewünschte Quellcode des jeweiligen Recipes mittels modify in den eigenen Arbeitsbereich unter ../workspace/sources umgesiedelt.

$ devtool modify [Recipe]

Dies ist allerdings auch notwendig, um gezielt nur ein bestimmtes Recipe bauen zu wollen. Das Recipe selbst wird dabei nicht in den Workspace übertragen, sondern nur der Quellcode. Sollten Abhängigkeiten bestehen, werden diese aus den dafür bereits vorgesehenen Recipes weiterhin eingebunden. Es sei denn, es sind auch dort Anpassungen notwendig oder gewollt, dann muss man diese natürlich ebenso in den Arbeitsbereich holen.

Um ein Solches Recipe wieder aus dem Arbeitsbereich abzukoppeln, wird reset verwendet.

$ devtool reset [Recipe]

Beim Reset wird das übertragene Recipe allerdings nicht vom Workspace gelöscht, was unter Umständen fatal wäre, sondern es wird im Buildsystem nur ein Verweis entfernt, der auf das Recipe im Workspace zeigt. Man kann also bei Bedarf wieder darauf zurückgreifen. Außerdem werden die gemachten Änderungen nicht zurückgeführt. Diese bleiben im Workspace.

Um Änderungen zu übertragen wird update-recipe verwendet.

Auf der Ziel-Hardware debuggen

Um direkt auf der Zielhardware debuggen zu können, gibt es natürlich den GDB. Falls GDB sich noch nicht auf der Zielhardware befindet, kann man GDB über die Paketverwaltung (opkg) auf der Zielhardware installieren, oder man holt sich GDB in den Workspace, baut es separat und überträgt es auf die Zielhardware:

$ devtool build gdb && devtool deploy-target gdb root@<BOX-IP>

Danach kann man GDB direkt auf der Zielhardware nutzen.

Zu beachten wäre noch, dass unter Umständen bestimmte Abhängikeiten, die evtl. parallel über die Layer-Repos angepasst wurden oder neu dazu gekommen sind, falls es notwendig ist in den Workspace geladen werden sollten. Natürlich müssen diese, falls es erforderlich ist, auch auf die Zielhardware geladen werden. Die Notwendigkeit dafür ergibt sich normalerweise immer dann, wenn bestimmte Libs fehlen oder sich geändert haben und dadurch beim Kompilieren Buildfehler auftreten oder Fehlfunktionen während der Ausführung auf der Zielhardware passieren. Alternativ wäre auch eine entprechende Anpassung der Paketverwaltung auf der Zielhardware möglich, die auf die Pakete der Entwicklungsumgebung Zugriff hat und damit aktuell gehalten werden kann.

Neutrino Log erstellen

Voraussetzung

Um ein Log via Konsole mit einem Yocto basierendem Image zu erhalten, reicht es journalctl im Vordergrund zu starten.

Für den Zugriff auf die jeweilige Box wird ssh oder telnet verwendet. Serielles Logging wäre auch möglich, benötigt aber evtl. zusätzliche Hardware wie entsprechende Kabel oder USB zu TTL-Adapter. Die Vorgehensweise ist aber ähnlich. Problematisch könnte dabei sein, dass diverse Adapter auch für die jeweilige Box oder dem Betriebssystem geeignet sind, was nicht immer der Fall ist. Das muss man leider herausfinden. Als Zugangssoftware können übliche Konsoletools verwendet werden. Unter Linux ist dies normalerweise standardmäßig immer vorhanden. Für Windows ginge z.B. Putty.

Verbinden mit der Box:

 login as: root
 __  __         __         ___       __
 \ \/ /__  ____/ /____    / _ \___  / /____ __
  \  / _ \/ __/ __/ _ \  / ___/ _ \/  '_/ // /
  /_/\___/\__/\__/\___/ /_/   \___/_/\_\\_, /
                                       /___/

 welcome to hd51 neutrino-hd image
 ➜  ~journalctl -f -u neutrino

Das war's eigentlich schon. Wenn ein vollständiges Log erwünscht ist, dann dieses Kommando verwenden:

 ➜  ~journalctl -u neutrino

Dies erlaubt die Anzeige mit den ältesten Logeinträgen, durch welche man sich bis zu den aktuellsten durch scrollen kann.

Log speichern

 ➜  ~journalctl -u neutrino > /tmp/neutrino_log.txt

Log auswerten

Journald verfügt über noch mehr sehr nützliche Optionen, um Ausgaben auszuwerten wie man es z.B. von grep her kennt.

* https://www.freedesktop.org/software/systemd/man/journalctl.html

Pakete erzeugen

$ devtool package [Paketname]

Devtool hat noch weitere Möglickeiten auf Lager. Eine Übersicht gibt

$ devtool -h

bzw. für die Unterkommandos

$ devtool <Unterkommando> -h


Die Vorgehensweise, um neue oder bestehende Receipes oder Layer zu erstellen oder zu warten, ist teilweise ähnlich. Weitere Informationen dazu findet man in der Devtool-Dokumentation.

Nützliches

Ausgabe der Vorgänge, die von einem Recipe ausgeführt werden. Dies zeigt z.b. Ausgaben beim Kompilieren der einzelnen Targets, vergleichbar mit den Ausgaben wie beim herkömmlichen make-Befehl:

bitbake -v <target>

Alle Archive herunterladen:

bitbake <target> --runall=fetch

Anzeige aller Aufgaben, die von einem Recipe ausgeführt werden:

bitbake -c listtasks <target>

Die mit bitbake -c listtasks angezeigten Aufgaben können auch einzeln ausgeführt werden z. B. do_compile:

bitbake -c compile <target>

Ausführung simulieren

bitbake -n <target>

Aufräumen, bewirkt die anschließende komplette Ausführung eines Recipes

bitbake -c cleansstate <target>

Debugausgabe aktivieren. Zeigt sehr ausführlich an, was im Hintergrund passiert.

bitbake -D  <target>

Sollte aus irgendeinem Grund der Bauvorgang hängenbleiben, was durchaus passieren kann, wenn Fehler an einem oder mehreren Targets vorhanden sind, könnte es sein, dass der Bitbake-Server blockiert ist. Absetzen von Tastatur-Befehlen wie Strg+c, bleiben in diesem Fall wirkungslos. Die Brechstange reboot hilft zwar, aber es reicht dieses Kommando:

rm -rf bitbake.lock

Hinweis: Fehler die solche "Hänger" verursachen müssen korrigiert werden, ansonsten wird dies immer wieder passieren!

SDK aktuell halten

Diese Funktion ist derzeit noch nicht verfügbar.

Weblinks