Yocto-BSP: ein Board Support Package bauen, das hält
Wie ein Yocto-BSP-Layer aufgebaut ist – Maschinenkonfiguration, Kernel und Device Tree, U-Boot, Image-Layout – und welche Regeln ihn von einem Yocto-LTS-Release zum nächsten wartbar halten.
Kurz gesagt: Ein Yocto-BSP ist ein Layer, der dem Build-System eine bestimmte Hardware beibringt: Maschinenkonfiguration, Kernel, Device Tree, Bootloader und Partitionslayout. In echten Projekten ist es oft etwas anderes – ein kopierter Hersteller-Layer, in den Distro-Einstellungen, Anwendungsrezepte und schnelle Korrekturen hineingewachsen sind und den niemand mehr auf das nächste Yocto-Release bringen kann. Die Regel, die das verhindert, ist einfach: Das BSP beschreibt die Hardware und sonst nichts, es liegt als eigener Layer über dem des Herstellers, und jeder Build ist gepinnt und wiederholbar.
Was ein BSP in Yocto ist
Der BSP-Leitfaden des Yocto Project sagt es ohne Umschweife: Ein BSP ist eine besondere Art von Layer. In seiner Mitte steht die Maschinenkonfiguration, die Datei, die ein Build über MACHINE auswählt. Sie hält alles zusammen, was der Layer sonst enthält – welcher Kernel verwendet wird, welche Device Trees gebaut werden, wie der Bootloader konfiguriert ist, welche serielle Konsole existiert und welche Image-Formate das Board braucht.
Im Produkt-Build ist das BSP ein Layer in einem Stapel:
| Layer | Enthält | Ausgewählt über |
|---|---|---|
| Produkt-Layer | Image-Rezepte, Ihre Anwendung, Konfiguration | das Image, das Sie bauen |
| Distro-Layer | Richtlinien: Init-System, Distro-Features, Sicherheitseinstellungen | DISTRO |
| Ihr BSP-Layer | Ihr Board: Maschinenkonfiguration, Änderungen an Kernel und U-Boot, Device Tree, Partitionslayout | MACHINE |
| BSP-Layer des Herstellers | SoC-Unterstützung: Kernel- und Bootloader-Rezepte, Firmware, GPU-Treiber | – |
| OpenEmbedded-Core | Kernrezepte und -klassen des Build-Systems | – |
Warum die Trennung zählt, steht in den Richtlinien für Yocto Project Compatible: Einen Layer zum Build hinzuzufügen, soll diesen Build nicht verändern, solange der Nutzer ihn nicht aktiviert – durch die Wahl einer MACHINE, einer DISTRO oder eines Distro-Features. Ein BSP-Layer, der erst wirkt, wenn seine Maschine ausgewählt ist, lässt sich mit jeder Distribution kombinieren, isoliert testen und auf das nächste Release bringen. Ein BSP-Layer, der nebenbei das Init-System setzt oder eine Anwendung installiert, nicht.
Das Hersteller-BSP: Grundlage, nicht Ziel
Der Layer des Herstellers – meta-freescale, der Community-BSP-Layer für NXP i.MX, meta-ti, meta-raspberrypi und ihre Gegenstücke – ist der richtige Ausgangspunkt. Er bringt mit, was niemand nachbauen will: SoC-Unterstützung, Rezepte für Kernel und Bootloader, den Boot-Container, Firmware und Grafiktreiber.
Für Ihre Änderungen ist er der falsche Ort. Wer ihn direkt bearbeitet, kann ihn nicht mehr aktualisieren: Jedes Hersteller-Release wird zum Merge. Stattdessen bleibt der Hersteller-Layer unverändert auf einer festen Revision, und alles, was Ihr Board ausmacht, kommt in einen eigenen Layer – als .bbappend-Dateien und eigene Konfiguration.
Vorsicht mit der Maschinenkonfiguration des Herstellers für das Evaluation-Kit. Sie beschreibt dieses Kit, nicht Ihr Board. In meta-freescale etwa nimmt die Include-Datei für das i.MX-8M-Mini-EVK die WLAN- und Bluetooth-Chips des Kits in MACHINE_FEATURES auf, und mit dem BSP von NXP hängen die EVK-Dateien Device Trees für die Display-, Audio- und PCIe-Varianten des Kits an. Wer seine Maschine unverändert davon ableitet, erbt Hardware, die er nicht hat – und Build-Fehler für Device Trees, die es für das eigene Board nicht gibt.
Der Aufbau des eigenen BSP-Layers
bitbake-layers create-layer erzeugt das Gerüst. Ausgefüllt sieht ein BSP-Layer für ein Board so aus:
meta-acme-bsp/
├── COPYING.MIT
├── README
├── SECURITY.md
├── conf/
│ ├── layer.conf
│ └── machine/
│ └── acme-panel.conf
├── files/
│ └── wic/
│ └── acme-panel.wks
├── recipes-bsp/
│ └── u-boot/
│ ├── u-boot-fslc_%.bbappend
│ └── u-boot-fslc/
│ └── 0001-board-add-ACME-control-panel.patch
└── recipes-kernel/
└── linux/
├── linux-fslc_%.bbappend
└── linux-fslc/
├── 0001-arm64-dts-freescale-add-ACME-control-panel.patch
└── acme-panel.cfg
README und Lizenzdatei sind keine Dekoration: Der BSP-Leitfaden verlangt beide für ein veröffentlichtes BSP, und das README soll die Abhängigkeiten des Layers nennen, beschreiben, wie man ihn baut und bootet, bekannte Probleme aufführen und sagen, wer ihn pflegt, samt Kontaktadresse für Patches. Seit Yocto 6.0 erwartet yocto-check-layer außerdem eine SECURITY.md, die beschreibt, wie Schwachstellen gemeldet werden. Neu ist auch das Verzeichnis files/wic/: Seit Yocto 6.0 (Wrynose) gehören Kickstart-Dateien für wic dorthin, und ein Build bricht ab, wenn sie noch in den alten Verzeichnissen wic/ oder scripts/lib/wic/canned-wks/ liegen. Genau solche Details entscheiden darüber, ob der Wechsel eines BSP auf ein neues Release einen Tag kostet oder eine Stunde.
conf/layer.conf macht den Layer für BitBake kenntlich:
BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "acme-bsp"
BBFILE_PATTERN_acme-bsp = "^${LAYERDIR}/"
BBFILE_PRIORITY_acme-bsp = "8"
LAYERDEPENDS_acme-bsp = "core freescale-layer"
LAYERSERIES_COMPAT_acme-bsp = "wrynose"
Zwei Zeilen sind wichtiger, als sie aussehen. LAYERDEPENDS macht die Abhängigkeit vom Hersteller-Layer ausdrücklich, sodass der Build mit einer klaren Fehlermeldung abbricht, wenn dieser Layer fehlt, statt ein seltsames Image zu erzeugen. LAYERSERIES_COMPAT nennt die Yocto-Releases, für die der Layer gedacht ist – nur die, die Sie tatsächlich bauen und testen, nicht jedes, mit dem er zufällig funktionieren könnte.
Die Maschinenkonfiguration
In der Maschinenkonfiguration wird Ihr Board zum Board. Eine Skizze für ein Trägerboard mit einem i.MX 8M Mini:
#@TYPE: Machine
#@NAME: ACME control panel
#@DESCRIPTION: ACME carrier board with an i.MX 8M Mini module
# SoC support from meta-freescale – deliberately not the EVK include,
# which also brings the evaluation kit's Wi-Fi chips and display variants
MACHINEOVERRIDES =. "mx8mm:"
require conf/machine/include/imx-base.inc
require conf/machine/include/arm/armv8a/tune-cortexa53.inc
# meta-freescale builds the community kernel and U-Boot (linux-fslc,
# u-boot-fslc); NXP's own linux-imx and u-boot-imx only with
# IMX_DEFAULT_BSP = "nxp". Decide this first – the bbappends depend on it.
# What makes this board this board
KERNEL_DEVICETREE = "freescale/imx8mm-acme-panel.dtb"
UBOOT_CONFIG ??= "emmc"
UBOOT_CONFIG[emmc] = "imx8mm_acme_panel_defconfig"
SERIAL_CONSOLES = "115200;ttymxc1"
MACHINE_FEATURES += "touchscreen"
# U-Boot and boot container (UBOOT_SUFFIX, UBOOT_DTB_NAME, SPL_BINARY,
# ATF_PLATFORM, DDR_FIRMWARE_NAME, ...): take the values from the EVK
# include and check each one against your board – the build stops without
# UBOOT_SUFFIX, and DDR type and boot medium differ more often than not.
# Image layout
IMAGE_FSTYPES = "wic.zst"
WKS_FILE = "acme-panel.wks"
Aufschlussreich ist auch, was hier nicht hingehört: DISTRO_FEATURES, das Init-System, Paketversionen, Benutzer, die Anwendung. All das sind Richtlinien; sie gehören in den Distro- oder Produkt-Layer. Eine Maschinenkonfiguration, die es setzt, macht aus dem BSP eine verkappte Distribution – und das nächste Produkt auf derselben Hardware erbt Entscheidungen, die es nie getroffen hat.
Kernel und Device Tree
Die meisten Produkt-BSPs bauen den Kernel, den ihr Hersteller-Layer bereitstellt, und ändern ihn über ein .bbappend. Vorher sollte allerdings klar sein, welcher Kernel das ist. meta-freescale bietet zwei an: das von der Community gepflegte linux-fslc, das standardmäßig gebaut wird, und NXPs eigenes linux-imx, das erst gebaut wird, wenn die Maschine IMX_DEFAULT_BSP = "nxp" setzt. Ein bbappend für das Rezept, das Ihre Maschine gar nicht baut, ändert nichts – kein Fehler, keine Warnung, nur Patches, die nie auf dem Gerät ankommen. bitbake-getvar PREFERRED_PROVIDER_virtual/kernel zeigt, welches es ist. Für den Standardfall:
# recipes-kernel/linux/linux-fslc_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append:acme-panel = " \
file://0001-arm64-dts-freescale-add-ACME-control-panel.patch \
file://acme-panel.cfg \
"
Entscheidend ist das Override :acme-panel. Es beschränkt die Änderung auf Ihre Maschine, sodass der Layer den Kernel jeder anderen Maschine unberührt lässt – genau das, was die Kompatibilitätsregel oben verlangt. yocto-check-layer prüft die allgemeine Form dieser Regel: Den Layer hinzuzufügen, darf keine Task-Signatur ändern, solange seine Maschine nicht ausgewählt ist.
Der Device Tree für Ihr Board kommt hier als Patch gegen den Kernel-Baum hinzu; alternativ baut die Klasse devicetree aus OpenEmbedded-Core Device-Tree-Quellen außerhalb des Kernel-Baums, einschließlich Overlays. So oder so steckt im Device Tree der größte Teil der eigentlichen Arbeit eines Bring-ups – ausführlich behandelt in Device Tree in der Praxis.
Kernel-Optionen gehören in Konfigurationsfragmente wie acme-panel.cfg, jeweils ein paar Zeilen CONFIG_…. Sie funktionieren mit jedem Kernel-Rezept, das die Klasse kernel-yocto erbt, und beide Kernel in meta-freescale tun das. Der häufige Fehler ist, menuconfig im Arbeitsverzeichnis des Builds aufzurufen und es dabei zu belassen: Die Änderung überlebt nur, bis die Konfiguration das nächste Mal neu erzeugt wird. bitbake -c diffconfig virtual/kernel schreibt den Unterschied in eine fragment.cfg im Arbeitsverzeichnis, und diese Datei gehört in den Layer. Für Änderungen am Kernel-Quelltext selbst machen devtool modify und devtool finish aus Ihren Commits Patches im Layer statt Änderungen in einem temporären Verzeichnis – das bbappend, das dabei entsteht, bindet sie allerdings ohne Bedingung ein; den SRC_URI-Eintrag schränken Sie danach auf Ihre Maschine ein.
U-Boot folgt demselben Muster: ein .bbappend mit dem Override Ihrer Maschine, die Board-Unterstützung als Patch und die Defconfig in der Maschinenkonfiguration benannt.
Das Image-Layout
Das Partitionslayout steht in der .wks-Datei, auf die WKS_FILE verweist: wo der Boot-Container liegt, welche Partitionen es gibt und wie groß sie sind. Für ein Produkt ist das kein Detail für später. Ein sicherer Update-Weg mit A/B-Partitionen – der Ansatz, den wir unter Cyber Resilience Act und sichere OTA-Updates empfehlen – braucht seine Partitionen vom ersten Image an. Das Layout von Geräten zu ändern, die schon im Feld sind, gehört zu den teuersten Änderungen, die ein BSP überhaupt brauchen kann.
Reproduzierbar und bereit für das nächste Release
Ein BSP, das nur im Verzeichnis eines einzelnen Entwicklers baut, ist ein Prototyp, kein Produkt-BSP. Drei Dinge machen es reproduzierbar:
- Gepinnte Layer. Jeder Layer auf einer festen Revision, festgehalten in einer versionierten Datei – mit kas oder mit
bitbake-setup, das mit Yocto 5.3 kam und mit 6.0 erstmals in einem LTS-Release steckt. Keine wandernden Branch-Stände, keinAUTOREVin einem Produkt-Build. - Ein Branch pro Yocto-Release. Der BSP-Layer bekommt für jedes unterstützte Release einen Branch mit dessen Namen und passendem
LAYERSERIES_COMPAT. Eine Korrektur landet auf jedem Branch, der noch unterstützt wird. - Ein CI-Build plus Boot-Test. Jede Änderung baut das Image und lässt
yocto-check-layer --machines acme-panelüber den Layer laufen. Danach bootet das Image auf echter Hardware – ein BSP, das zwar baut, aber das Display nicht mehr hochbringt, fällt in keinem Build-Log auf. Darum geht es in unserem Artikel über Hardware-in-the-Loop-Testing.
Das Tempo gibt der Release-Kalender vor. Alle zwei Jahre erscheint ein neues LTS-Release, das vier Jahre unterstützt wird; die Releases dazwischen werden sieben Monate unterstützt. Wrynose (6.0), erschienen im Mai 2026, wird bis April 2030 unterstützt, Scarthgap (5.0) bis April 2028. Kirkstone, das LTS davor, hat sein Support-Ende im Frühjahr 2026 erreicht. Ein Produkt mit zehn Jahren Lebensdauer durchläuft also mehrere LTS-Wechsel – und wie teuer jeder einzelne wird, hängt fast vollständig davon ab, wie sauber der BSP-Layer ist. Wenn noch offen ist, ob Yocto überhaupt das richtige Werkzeug ist, hilft unser Vergleich Yocto oder Buildroot.
Die Fehler, die wir am häufigsten sehen
| Fehler | Folge | Besser |
|---|---|---|
| Hersteller-Layer direkt bearbeitet | jedes Hersteller-Update wird zum Merge | Hersteller-Layer unverändert, Änderungen als bbappends |
| Distro-Richtlinien in der Maschinenkonfiguration | das BSP entscheidet, was es nicht soll | Richtlinien im Distro-Layer |
| Image- und Anwendungsrezepte im BSP | ein zweites Produkt kann das Board nicht nutzen | eigener Produkt-Layer |
| bbappends ohne Maschinen-Override | der Layer verändert die Builds anderer Maschinen | :append:<machine> und Verwandte |
| Kernel-Optionen im Arbeitsverzeichnis gesetzt | beim nächsten sauberen Build verloren | Fragmente über diffconfig |
| Wandernde Revisionen | zwei Builds, zwei verschiedene Images | jeder Layer und jede SRCREV gepinnt |
| Kein README, kein Verantwortlicher | Wissen geht mit einer Person | README, wie der BSP-Leitfaden es beschreibt |
Nichts davon ist exotisch, und jeder dieser Fehler ist am Anfang billig zu vermeiden und später teuer zu beheben.
Fazit
Ein langlebiges Yocto-BSP ist vor allem eine Frage der Disziplin: ein eigener Layer über dem unveränderten Hersteller-Layer, eine Maschinenkonfiguration, die Hardware beschreibt und sonst nichts, bbappends mit Maschinen-Override, Kernel-Optionen als Fragmente, alles gepinnt und auf echter Hardware getestet. Dann ist der Wechsel auf das nächste LTS-Release ein geplantes Stück Arbeit statt eines eigenen Projekts.
Wenn Sie ein BSP aufbauen, ein geerbtes übernehmen oder den Wechsel auf Wrynose planen: Genau das leistet unser Angebot Yocto-BSP & Distributionen; das Board-Bring-up darunter gehört zu unserer Embedded-Linux-Entwicklung. Wenn Ihr Team das Wissen lieber selbst aufbaut, behandelt die Yocto-Schulung Layer, Rezepte und BSP-Arbeit praktisch. Oder sprechen Sie uns direkt an.
Häufige Fragen
- Was ist der Unterschied zwischen einem BSP-Layer und einem Distro-Layer?
- Der BSP-Layer beschreibt Hardware: Maschinenkonfiguration, Kernel, Device Tree, Bootloader und Firmware. Der Distro-Layer beschreibt Richtlinien: Init-System, Distro-Features, Sicherheitseinstellungen und Paketauswahl. Ein Build wählt das eine über MACHINE und das andere über DISTRO. Diese Trennung erlaubt es, dieselbe Distribution auf ein zweites Board zu bringen oder eine zweite Distribution auf dasselbe Board.
- Können wir das BSP des Herstellers einfach so verwenden?
- Für den Einstieg ja. Für ein Produkt gehört ein eigener BSP-Layer darüber, der Hersteller-Layer wird auf eine feste Revision gepinnt, und jede Änderung läuft über bbappends. Die Maschinenkonfiguration des Herstellers beschreibt sein Evaluation-Kit – einschließlich Chips und Display-Varianten, die Ihr Board nicht hat.
- Auf welchem Yocto-Release sollte ein neues Produkt starten?
- Auf dem aktuellen LTS-Release, sofern der Layer Ihres SoC-Herstellers es unterstützt. Das ist Wrynose (6.0), erschienen im Mai 2026 und unterstützt bis April 2030. Scarthgap (5.0) wird bis April 2028 unterstützt – ein Produkt darauf hat Zeit, sollte den Wechsel aber planen, statt auf die Frist zu warten.
- Wie bleibt ein BSP über mehrere Yocto-Releases wartbar?
- Ein Branch pro Yocto-Release, LAYERSERIES_COMPAT auf die Releases gesetzt, die Sie tatsächlich bauen, alle Layer gepinnt, dazu yocto-check-layer und ein Boot-Test auf echter Hardware in der CI. Patches, die upstream hingehören – ein Device Tree für ein öffentlich erhältliches Modul, eine Treiberkorrektur –, sollten dorthin, denn jeden Patch, den Sie selbst mitführen, müssen Sie beim nächsten Release erneut mitführen.
Mehr zu diesen Themen
Geschäftsführer, bitshift dynamics
Entwickelt mit seinem Team hardwarenahe Software für Embedded-Produkte – C++, Qt/QML, Embedded Linux und das Yocto Project. bitshift dynamics arbeitet seit 2005 in diesem Feld.