Dans la séquence précédente, nous avons modifié le fichier
«local.conf
» que nous trouvons dans
le sous-répertoire «conf/
» de notre répertoire
de build.
Les modifications étaient assez simples : ajustement de
l’emplacement des dossiers de stockage temporaire, ajout d’utilisateur
et configuration de mots de passe, puis modification du nom de machine.
Dans cette séquence nous allons ajouter quelques applications sur notre système. Pour cela, nous allons commencer en modifiant à nouveau ce fichier, puis nous créerons notre propre recette d'image personnalisée.
Notre première possibilité est d’ajouter des packages dont
les recettes sont livrées avec Poky.
Regardons, par exemple les fichiers se trouvant dans les
sous-répertoires «recipes*/
» du layer meta
de Poky :
[build-qemu]$ ls ../../layers/poky/meta*/recipes-* ../../layers/poky/meta/recipes-bsp: acpid efibootmgr formfactor grub libacpi opensbi pm-utils u-boot usbutils alsa-state efivar gnu-efi keymaps lrzsz pciutils setserial usbinit v86d ../../layers/poky/meta/recipes-connectivity: avahi connman iproute2 libnss-mdns mobile-broadband-provider-info ofono ppp slirp wpa-supplicant bind dhcpcd iw libpcap neard openssh ppp-dialin socat bluez5 inetutils kea libuv nfs-utils openssl resolvconf ssh-pregen-hostkeys ../../layers/poky/meta/recipes-core: base-files dbus-wait gettext images libcgroup ncurses packagegroups systemd util-linux base-passwd dropbear glib-2.0 init-ifupdown libxcrypt netbase psplash sysvinit volatile-binds busybox ell glib-networking initrdscripts libxml newlib readline ttyrun zlib coreutils expat glibc initscripts meta os-release seatd udev dbus fts ifupdown kbd musl ovmf sysfsutils update-rc.d ../../layers/poky/meta/recipes-devtools: apt cmake dosfstools gdb libcomps makedevs patchelf rsync tcltk autoconf createrepo-c dpkg git libdnf meson perl ruby unfs3 autoconf-archive debugedit dwarfsrcfiles gnu-config libedit mmc perl-cross run-postinsts unifdef automake dejagnu e2fsprogs go libmodulemd mtd pkgconf rust vala binutils desktop-file-utils elfutils help2man librepo mtools pkgconfig squashfs-tools valgrind bison devel-config erofs-utils i2c-tools libtool nasm pseudo strace xmlto bootchart2 diffstat expect icecc-create-env llvm ninja python subversion btrfs-tools distcc fdisk icecc-toolchain log4cplus opkg qemu swig ccache dmidecode file intltool lua opkg-utils quilt syslinux cdrtools dnf flex jquery m4 orc repo systemd-bootchart chrpath docbook-xml gcc json-c make patch rpm tcf-agent ../../layers/poky/meta/recipes-extended: acpica cronie gperf libarchive lsb msmtp psmisc sysklogd wget asciidoc cups grep libidn lsof net-tools quota sysstat which at cwautomacros groff libmnl ltp newt rpcbind tar xdg-utils baremetal-example diffutils gzip libnsl lzip packagegroups rpcsvc-proto tcp-wrappers xinetd bash ed hdparm libnss-nis man-db pam screen texinfo xz bc ethtool images libpipeline man-pages parted sed texinfo-dummy-native zip blktool findutils iptables libsolv mc pbzip2 shadow time zstd bzip2 gawk iputils libtirpc mdadm perl slang timezone cpio ghostscript less lighttpd mingetty pigz stress-ng unzip cracklib go-examples libaio logrotate minicom procps sudo watchdog ../../layers/poky/meta/recipes-gnome: epiphany gi-docgen gsettings-desktop-schemas hicolor-icon-theme libdazzle libnotify libsecret gcr gnome gtk+ json-glib libgudev libportal libxmlb gdk-pixbuf gobject-introspection gtk-doc libadwaita libhandy librsvg ../../layers/poky/meta/recipes-graphics: builder glslang libepoxy menu-cache shaderc wayland xorg-lib cairo graphene libfakekey mesa spir x11-common xorg-proto cantarell-fonts harfbuzz libmatchbox mini-x-session startup-notification xcursor-transparent-theme xorg-util drm igt-gpu-tools libsdl2 packagegroups ttf-fonts xinput-calibrator xorg-xserver fontconfig images libva pango virglrenderer xorg-app xrestop freetype jpeg matchbox-session piglit vulkan xorg-driver xwayland glew kmscube matchbox-wm pong-clock waffle xorg-font ../../layers/poky/meta/recipes-kernel: blktrace dtc kexec libtraceevent linux-firmware lttng modutils-initscripts powertop wireless-regdb cryptodev kern-tools kmod linux linux-libc-headers make-mod-scripts perf systemtap ../../layers/poky/meta/recipes-multimedia: alsa flac lame libogg libpng libsndfile libtiff mpeg2dec pulseaudio speex x264 ffmpeg gstreamer liba52 libomxil libsamplerate libtheora libvorbis mpg123 sbc webp ../../layers/poky/meta/recipes-rt: README images rt-tests ../../layers/poky/meta/recipes-sato: images matchbox-config-gtk matchbox-panel-2 matchbox-theme-sato pulseaudio-sato sato-icon-theme shutdown-desktop l3afpad matchbox-desktop matchbox-sato packagegroups puzzles sato-screenshot webkit libptytty matchbox-keyboard matchbox-terminal pcmanfm rxvt-unicode settings-daemon ../../layers/poky/meta/recipes-support: appstream curl gnutls libdaemon libksba libunistring nghttp2 shared-mime-info apr db gpgme libevdev libmd libunwind npth sqlite argp-standalone debianutils icu libevent libmicrohttpd liburcu nss-myhostname taglib aspell diffoscope iso-codes libexif libmpc libusb numactl user-creation atk dos2unix itstool libffi libnl libxslt p11-kit utfcpp attr enchant libassuan libfm libpcre libyaml pinentry vim bash-completion fribidi libatomic-ops libgcrypt libproxy lz4 popt vte bmaptool gdbm libbsd libgit2 libpsl lzo ptest-runner xxhash boost gmp libcap libgpg-error libseccomp lzop re2c ca-certificates gnome-desktop-testing libcap-ng libical libsoup mpfr rng-tools consolekit gnupg libcheck libjitterentropy libssh2 nettle serf
La liste n’est pas évidente à lire, mais un comptage rapide avec
«find ../../layers/poky/meta -name '*bb'| wc -l
»
nous indique la présence de plus de 900 recettes livrées dans Poky. La
plupart d’entre-elles sont des services ou des utilitaires bas-niveaux
assez peu visibles au premier abord. Nous pouvons toutefois ajouter sur
notre image un petit outil que j’aime bien :
mc
le Midnight Commander.
Pour cela nous ajoutons simplement la ligne suivante dans
local.conf
:
IMAGE_INSTALL:append = " mc"
La variable «IMAGE_INSTALL
»
contient la liste des noms de packages à installer sur le
système cible.
Le suffixe «:append
» indique
que la chaîne fournie en partie droite de l'affectation doit être
ajoutée à la fin de la variable concernée.
Nous ajoutons donc le nom du package mc
précédé
d'une espace qui sert de séparateur entre les éléments de la liste de
packages.
Nous pourrions également utiliser :
IMAGE_INSTALL:prepend = "mc "
pour ajouter la chaîne en début de variable (et en la faisant suivre de l'espace de séparation).
Plusieurs lignes de ce type peuvent se suivre pour allonger d’autant le contenu de l’image.
Après avoir regénéré «core-image-base
» et nous
être connectés, nous pouvons lancer la commande
«mc
» et retrouver l'atmosphère un peu surannée
des années 1990 sur Ms-Dos
(figure II.2-1). Malgré son aspect
désuet aujourd'hui, cet outil peut encore s'avérer très pratique lors
de la mise au point d’un système embarqué pour le confort du
développement en ligne de commande.
Il existe d’autres outils dont les recettes se trouvent dans Poky que
j’aime bien intégrer dans mes images embarquées afin de permettre la
mise au point du système ou du code métier : dtc
,
valgrind
, powertop
,
gdbserver
… Nous en reparlerons dans la troisième
partie, pour l’instant contentons-nous d’ajouter les lignes
suivantes :
IMAGE_INSTALL:append = " mc" IMAGE_INSTALL:append = " dtc valgrind" IMAGE_INSTALL:append = " gdbserver powertop"
Comme on le voit, on peut aussi bien enchaîner des lignes d’ajout que regrouper les différents packages désirés dans une seule ligne.
Après recompilation de l’image, je vérifie la présence des outils ajoutés. Je ne m’intéresse pas ici à leurs fonctionnements ou leurs résultats, juste à leurs présences sur ma cible :
Poky (Yocto Project Reference Distro) 5.0.2 mybox /dev/ttyAMA0 mybox login: root Password: (linux) WARNING: Poky is a reference Yocto Project distribution that should be used for testing and development purposes only. It is recommended that you create your own distribution for production use. root@mybox:~# dtc --version Version: DTC v1.7.0+ root@mybox:~# valgrind --version valgrind-3.22.0 root@mybox:~# gdbserver --version GNU gdbserver (GDB) 14.2 Copyright (C) 2023 Free Software Foundation, Inc. gdbserver is free software, covered by the GNU General Public License. This gdbserver was configured as "arm-poky-linux-gnueabi" root@mybox:~# powertop --version PowerTOP version 2.15 root@mybox:~#
Pendant la mise au point d’un système embarqué, on a souvent besoin
d’éditer des fichiers directement sur la cible. Sur une installation
«core-image-base
»,
nous disposons bien de l’éditeur
«vi
», intégré
dans le package busybox
. Néanmoins tout le monde n’est pas
familier des commandes de vi
, et l’utilisation d’un outil
un peu plus intuitif s’avère généralement plus reposante.
Supposons que nous souhaitions installer l'éditeur
«nano
» par exemple, qui est plus
simple d’emploi que vi
.
Essayons simplement d’ajouter la ligne :
IMAGE_INSTALL:append = " nano"
dans notre fichier «local.conf
». Dès le lancement du build
bitbake
va se plaindre, nous afficher une série de lignes
rouges et terminer en indiquant une erreur :
ERROR: Nothing RPROVIDES 'nano' (but /home/Builds/Lab/Yocto-lab/poky/meta/recipes-core/images/core-image-base.bb RDEPENDS on or otherwise requires it) NOTE: Runtime target 'nano' is unbuildable, removing... Missing or unbuildable dependency chain was: ['nano'] ERROR: Required build target 'core-image-base' has no buildable providers. Missing or unbuildable dependency chain was: ['core-image-base', 'nano'] Summary: There were 2 ERROR messages, returning a non-zero exit code.
Visiblement, bitbake
n’a pas trouvé dans les recettes
fournies par Poky celle permettant de construire nano
.
Il va probablement nous falloir trouver un layer (un ensemble de recettes) à installer sur notre système. Pour cela, l'usage est de se rendre sur le site https://layers.openembedded.org, de cliquer sur l’onglet «recipes», de sélectionner la version de Poky qui nous concerne et de saisir le nom du package désiré dans le moteur de recherche. Nous trouvons alors une page de résultat comme celle de la figure II.2-2.
Clairement la recette qui m’intéresse est la première de la liste. Elle
se trouve dans le layer indiqué dans la colonne de droite :
«meta-oe
». En cliquant sur ce lien je vois
qu’il s’agit d’un layer appartenant à un repository
nommé «meta-openembedded
», et je trouve
l’adresse du téléchargement à effectuer.
Rappelons que les layers sont des répertoires contenant des
recettes. Les layers ont un nom qui commence par
«meta-
». À cet égard,
«meta-openembedded
» est plutôt mal nommé, car
il ne s'agit pas d'un dépôt mais d'un ensemble de dépôts. J'aurais trouvé plus
logique de l'appeler «openembedded-layers
» par exemple.
[build-qemu]$ cd ../../layers/ [layers]$ git clone git://git.openembedded.org/meta-openembedded -b scarthgap Cloning into 'meta-openembedded'... remote: Enumerating objects: 246096, done. remote: Counting objects: 100% (673/673), done. remote: Compressing objects: 100% (227/227), done. remote: Total 246096 (delta 437), reused 505 (delta 422), pack-reused 245423 Receiving objects: 100% (246096/246096), 60.65 MiB | 16.06 MiB/s, done. Resolving deltas: 100% (150463/150463), done. [layers]$ ls meta-openembedded/ contrib meta-filesystems meta-initramfs meta-networking meta-perl meta-webserver README.md COPYING.MIT meta-gnome meta-multimedia meta-oe meta-python meta-xfce [layers]$ cd ../builds/build-qemu/ [build-qemu]$
L’ensemble
«meta-openembedded
» est assez
incontournable dès lors que l’on prépare un système avec Yocto. Il
contient plus de deux mille recettes pour de nombreux packages
très utiles pour Linux embarqué.
Nous devons ajouter le layer «meta-oe
»
à la liste de ceux pris en compte dans notre build. C'est le
rôle de la sous-commande «add-layer
» de la
commande «bitbake-layers
» fournie par Poky.
[build-qemu]$ bitbake-layers add-layer ../../layers/meta-openembedded/meta-oe/ NOTE: Starting bitbake server... [build-qemu]$
Nous pouvons à présent relancer notre compilation, elle se déroule
normalement et nano
est intégré dans notre image.
[build-qemu]$ bitbake core-image-base [...]
Par exemple, sur
la figure II.2-3, nous l'employons pour
consulter le fichier /etc/passwd
.
Nous avons utilisé la compilation avec
«core-image-base
» un peu aveuglément, sans
comprendre véritablement ce que cela signifie. Nous allons examiner son
contenu plus en détail.
Pour cela nous recherchons le fichier qui décrit
«core-image-base
» dans les sous-répertoires de
Poky. Il s’agit d’une recette avec l’extension
«.bb
».
[build-qemu]$ find ../../layers/poky/ -name core-image-base.bb ../../layers/poky/meta/recipes-core/images/core-image-base.bb
Lorsque nous demandons à bitbake
de produire une image, il
recherche un fichier d'extension «.bb
» avec le
nom de l'image. Ce fichier doit se trouver dans un sous-répertoire
«images/
» se trouvant dans un répertoire dont
le nom commence par «recipes-
»
Le fichier trouvé correspond bien à ces critères. Voyons son contenu.
[build-qemu]$ cat ../../layers/poky/meta/recipes-core/images/core-image-base.bb SUMMARY = "A console-only image that fully supports the target device \ hardware." IMAGE_FEATURES += "splash" LICENSE = "MIT" inherit core-image
Hormis la description et la licence, deux lignes nous intéressent :
inherit core-image
» :
la recette hérite d’une classe prédéfinie qui décrit le contenu
d’une image en proposant des fonctionnalités optionnelles.
IMAGE_FEATURES += "splash"
»
ajoute la fonctionnalité splashscreen à notre image.
Dans la définition de la classe image
, une
ligne (modifiée pour simplification) dit en substance
«FEATURE_PACKAGES_splash = "psplash"
»
pour indiquer quel package doit être ajouté pour répondre à
cette fonctionnalité.
Nous voyons que Yocto nous propose ainsi ce mécanisme de features d'image, des fonctionnalités de haut-niveau que l’on peut sélectionner sans se soucier du détail du ou des packages correspondants.
Voici quelques fonctionnalités proposées par la classe
«core-image
», qui est implémentée dans le
fichier ../../layers/poky/meta/classes-recipe/core-image.bbclass
.
x11 | Serveur X-window |
x11-base | Serveur X-window et environnement minimal (Matchbox) |
x11-sato | Serveur X-window et environnement Sato pour mobile. |
weston | Environnemnt graphique Wayland et compositeur Weston. |
tools-debug | Outils de débogage (gdb , gdbserver , strace , gcore …) |
eclipse-debug | Outils de débogage distant avec Eclipse. |
tools-profile | Outils de profiling (perf , lttng , gprof ...) |
tools-testapps | Outils de tests du matériel. |
tools-sdk | Installation des outils de développement natifs (gcc , make ...) sur la cible. |
nsf-server | Serveur NFS |
nfs-client | Client NFS |
ssh-server-dropbear | Serveur SSH basé sur Dropbear. |
ssh-server-openssh | Serveur SSH basé sur Openssh |
hwcodecs | Support des codecs pour l’accélération matérielle |
package-management | Support des packages sur la cible (installation des outils et base de données). |
dev-pkgs | Installation des fichiers headers nécessaire pour le développement des packages présents. |
dbg-pkgs | Tous les packages sont compilés avec les informations de débogage |
doc-pkgs | Installation de la documentation associée à tous les packages |
bash-completion-pkgs | Complétions de la ligne de commande de Bash |
read-only-rootfs | Système de fichiers en lecture-seule. |
splash | Écran d’accueil pendant le boot |
... |
Nous pouvons, par exemple, ajouter dans notre fichier
local.conf
la ligne :
IMAGE_FEATURES += "tools-sdk"
pour intégrer dans notre image les outils nécessaires à la compilation de code directement sur la cible. La compilation ci-dessous a bien lieu sur ma cible ARM émulée par Qemu :
mybox login: root Password: (linux) root@mybox:~# nano my-hello.c #include <stdio.h> #include <unistd.h> int main(void) { char host[512]; gethostname(host, 512); printf("Hello from %s\n", host); return 0; } root@mybox:~# gcc my-hello.c -o my-hello -Wall root@mybox:~# ./my-hello Hello from mybox root@mybox:~# g++ --version g++ (GCC) 13.3.0 [...] root@mybox:~#
Il n’est pas fréquent d’installer une chaîne de compilation native directement sur la plateforme cible, mais cela peut s’avérer intéressant pendant la phase de prototypage et de mise au point. Il s’agit d’un point sur lequel Yocto est plus puissant que son confrère Buildroot qui a renoncé à cette possibilité il y a quelques années.
Jusqu’à présent nous avons utilisé l’image core-image-base
en ajoutant dans local.conf
des lignes
«IMAGE_INSTALL:append
» et «IMAGE_FEATURES +=
»
Cette approche est parfaitement adaptée pour les premières phases de
configuration du système, mais trouve rapidement ses limites. Pour les
systèmes industriels en effet, il est souvent nécessaire de gérer toute
une gamme de produits différents. On est donc amenés à réaliser
régulièrement des séries de builds avec peu de différences
entre-eux. On préfère généralement factoriser toute la configuration
commune aux différents produits dans une image particulière et ne
laisser dans les fichiers local.conf
que les spécificités
propres à chaque build.
Autrement dit nous allons créer notre propre fichier de
description d’image, et nous n’invoquerons
plus «bitbake core-image-base
» mais
«bitbake my-image
» par exemple (en situation
réelle, je nomme plutôt l’image en fonction du projet de mon client).
Pour cela, nous devons commencer par créer notre propre
layer. Rien de compliqué, l’outil
«bitbake-layers
» est là pour nous aider.
[build-qemu]$ bitbake-layers create-layer ../../layers/meta-my-layer NOTE: Starting bitbake server... Add your new layer with 'bitbake-layers add-layer ../meta-my-layer' [build-qemu]$ ls ../../layers meta-my-layer meta-openembedded meta-raspberrypi poky [build-qemu]$ ls ../../layers/meta-my-layer/ conf COPYING.MIT README recipes-example [build-qemu]$
Dans le layer nouvellement créé nous trouvons un squelette de fichier `README`, un exemplaire de la license MIT, un répertoire `recipes-example` contenant un recette minimale affichant un message et un répertoire `conf` contenant un fichier `layer.conf` correspondant aux paramétrages du layer.
[build-qemu]$ cat ../../layers/meta-my-layer/conf/layer.conf # We have a conf and classes directory, add to BBPATH BBPATH .= ":${LAYERDIR}" # We have recipes-* directories, add to BBFILES BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend" BBFILE_COLLECTIONS += "meta-my-layer" BBFILE_PATTERN_meta-my-layer = "^${LAYERDIR}/" BBFILE_PRIORITY_meta-my-layer = "6" LAYERDEPENDS_meta-my-layer = "core" LAYERSERIES_COMPAT_meta-my-layer = "scarthgap"
Dans ce fichier, deux variables sont particulièrement utiles :
BBFILE_PRIORITY_<layer-name>
qui contient la priorité
du layer c'est à dire sa position dans l'ordre de parcours des recettes
par Bitbake. Plus grande est la priorité, plus tard le layer est parcouru.
Nous y reviendrons.LAYERSERIES_COMPAT_<layer-name>
contient la liste des
versions de Poky avec lesquelles le layer est compatible. Le caractère
séparateur entre les noms de versions est l'espace. Ceci est principalement
utile quand une même recette sert dans des builds pour différentes générations
d'un produit.
Le layer est bien créé mais, comme
«bitbake-layers
» nous l’affiche de manière un
peu ambiguë, il n’est pas encore intégré dans la liste des
layers que bitbake
parcourera lors des
builds. Nous devons l’y ajouter :
[build-qemu]$ bitbake-layers show-layers NOTE: Starting bitbake server... layer path priority ========================================================================== meta /home/Builds/Lab/Yocto-lab/layers/poky/meta 5 meta-poky /home/Builds/Lab/Yocto-lab/layers/poky/meta-poky 5 meta-yocto-bsp /home/Builds/Lab/Yocto-lab/layers/poky/meta-yocto-bsp 5 meta-oe /home/Builds/Lab/Yocto-lab/layers/meta-openembedded/meta-oe 5 [build-qemu]$ bitbake-layers add-layer ../../layers/meta-my-layer/ NOTE: Starting bitbake server... [build-qemu]$ bitbake-layers show-layers NOTE: Starting bitbake server... layer path priority ========================================================================== meta /home/Builds/Lab/Yocto-lab/layers/poky/meta 5 meta-poky /home/Builds/Lab/Yocto-lab/layers/poky/meta-poky 5 meta-yocto-bsp /home/Builds/Lab/Yocto-lab/layers/poky/meta-yocto-bsp 5 meta-oe /home/Builds/Lab/Yocto-lab/layers/meta-openembedded/meta-oe 5 meta-my-layer /home/Builds/Lab/Yocto-lab/layers/meta-my-layer 6 [build-qemu]$
Nous créons dans notre layer un début d'arborescence pour
héberger nos recettes personnelles.
Son nom doit commencer par «recipes-
».
Je choisis arbitrairement «recipes-custom
»,
pour les projets de mes clients, je travaille souvent dans
«recipes-<nom-de-l-entreprise>
».
[build-qemu]$ mkdir ../../layers/meta-my-layer/recipes-custom/
Il faut ensuite y créer un sous-répertoire nommé
«images
» pour stocker nos recettes décrivant
des images. Puis nous y copions le fichier
core-image-base.bb
pour avoir un point de départ.
[build-qemu]$ mkdir ../../layers/meta-my-layer/recipes-custom/images/ [build-qemu]$ cp ../../layers/poky/meta/recipes-core/images/core-image-base.bb ../../layers/meta-my-layer/recipes-custom/images/my-image.bb
En le copiant, j'ai renommé le fichier
«core-image-base.bb
» en
«my-image.bb
».
Éditons-le, pour obtenir par
exemple le contenu suivant :
[build-qemu]$ nano ../../layers/meta-my-layer/recipes-custom/images/my-image.bb SUMMARY = "A customized image for development purposes." LICENSE = "MIT" inherit core-image IMAGE_FEATURES += "splash" IMAGE_FEATURES += "tools-debug" IMAGE_FEATURES += "tools-profile" IMAGE_FEATURES += "tools-sdk" IMAGE_FEATURES += "ssh-server-dropbear" IMAGE_INSTALL:append = " mc" IMAGE_INSTALL:append = " nano"
Nous éditons local.conf
pour supprimer toutes les lignes
«IMAGE_INSTALL:append
» et
«IMAGE_FEATURES
» que nous avions ajoutées
auparavant et lançons le nouveau build avec :
[build-qemu]$ bitbake my-image
Après compilation, nos fichiers seront disponibles dans
tmp/deploy/images/qemuarm/
avec le préfixe
«my-image-qemuarm-
». Au lancement,
runqemu
utilise la configuration la plus récente.
Néanmoins, il est possible de préciser le nom de l'image pour éviter
toute confusion ainsi :
[build-qemu]$ runqemu nographic my-image
On peut noter, dans la recette d'image ci-dessus la présence de deux syntaxes différentes pour ajouter une chaîne de caractères à la fin du contenu d'une variable :
IMAGE_FEATURES += "splash"
» :
ajoute la chaîne splash
en la précédant
automatiquement d'une espace
IMAGE_INSTALL:append = " mc"
» :
ajoute la chaîne mc
et l'espace que nous avons
explicitement indiquée.
Mais la différence entre ces deux syntaxes ne se limite pas uniquement
à cette histoire d'espace. Sinon nous utiliserions toujours
«+=
» qui semble plus simple.
+=
» l'évaluation du contenu
précédent, auquel ajouter la chaîne se fait
immédiatement à l'analyse de la ligne.
La variable IMAGE_FEATURES
est initialisée avec
une chaîne vide dans le fichier
poky/meta/classes-recipe/image.bbclass
chargé par
héritage depuis le fichier
poky/meta/classes-recipe/core-image.bbclass
. Après
lecture de notre recette d'image, le contenu de
IMAGE_FEATURES
est donc exactement
«splash tools-debug tools-profile tools-sdk ssh-server-dropbear
».
:append
», l'évaluation du
contenu de la chaîne avant ajout est différée
et n'a lieu qu'une fois que bitbake
a lu et
initialisé toutes les variables d'environnement.
IMAGE_INSTALL
est initialisée dans
poky/meta/classes-recipe/core-image.bbclass
avec IMAGE_INSTALL ?= "${CORE_IMAGE_BASE_INSTALL}
"CORE_IMAGE_BASE_INSTALL
étant remplie
quelques lignes auparavant). L'affectation
«?=
» indique que la
variable n'est initialisée que si elle n'existe pas au
préalable. Si nous avions utilisé «+=
»
pour ajouter mc
et nano
,
l'initialisation de IMAGE_INSTALL
dans
core-image-base
n'aurait pas eu lieu, celle-ci
n'aurait contenu que " mc nano
" et notre système
aurait été inutilisable.
Savoir quand utiliser «+=
» et quand préférer
«:append
» n'est pas simple quand il s'agit de
compléter des variables initialisées dans des recettes fournies par
Poky (ou par des layers supplémentaires, notamment pour le
support du matériel). Il est souvent nécessaire d'aller jeter un
œil sur l'implémentation des recettes, et il est bon de se
familiariser avec l'arborescence de poky/
et celle de
meta-openembedded/
par exemple.
On peut toutefois préciser quelques cas d'usage habituels
IMAGE_INSTALL
on utilisera toujours
«:append
» IMAGE_FEATURES
, DISTRO_FEATURES
,
MACHINE_FEATURES
, etc. on utilisera plutôt
«+=
»FILES_EXTRA_PATHS
on utilisera «:append
» ou «:prepend
» pour
pouvoir indiquer explicitement le séparateur de la liste, qui
est un deux-points «:
»+=
» tout en sachant que si
l'initialisation ne se fait pas comme on l'attend, on basculera sur
«:append
»Depuis la version Scarthgap (5.0) de Poky, un message d'avertissement apparaît à la connexion :
Poky (Yocto Project Reference Distro) 5.0.2 mybox /dev/ttyAMA0 mybox login: root Password: (linux) WARNING: Poky is a reference Yocto Project distribution that should be used for testing and development purposes only. It is recommended that you create your own distribution for production use. root@mybox:~#
Ce message nous indique que la distribution «poky
»
(une distro dans la terminologie de Yocto) inclut des fonctionnalités
utiles pour tester ou déboguer des systèmes mais qui ne sont pas recommandées
sur un système en production (pour des problèmes de robustesse et surtout de
sécurité).
Il faut bien distinguer deux choses :
bitbake
», des layers comme «poky/meta
»
et ses nombreuses recettes, ainsi que des outils supplémentaires comme
«bitbake-layers
», «devtool
» ou
«recipetool
». C'est le «Poky» que l'on
télécharge et dont les versions sont nommées Dunfell, Kirkstone ou Scarthgap.
poky
qui est
sélectionnée par défaut, qui définit des fonctionnalités et qui fixe des choix que
l'on va être amenés à modifier.
La distro poky
est définie dans le fichier suivant :
[build-qemu]$ cat ../../layers/poky/meta-poky/conf/distro/poky.conf DISTRO = "poky" DISTRO_NAME = "Poky (Yocto Project Reference Distro)" DISTRO_VERSION = "5.0.2" DISTRO_CODENAME = "scarthgap" SDK_VENDOR = "-pokysdk" SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${METADATA_REVISION}', 'snapshot')}" SDK_VERSION[vardepvalue] = "${SDK_VERSION}" MAINTAINER = "Poky Maintainers <poky@lists.yoctoproject.org>" TARGET_VENDOR = "-poky" LOCALCONF_VERSION = "2" # Override these in poky based distros POKY_DEFAULT_DISTRO_FEATURES = "opengl ptest multiarch wayland vulkan" POKY_DEFAULT_EXTRA_RDEPENDS = "packagegroup-core-boot" POKY_DEFAULT_EXTRA_RRECOMMENDS = "kernel-module-af-packet" DISTRO_FEATURES ?= "${DISTRO_FEATURES_DEFAULT} ${POKY_DEFAULT_DISTRO_FEATURES}" PREFERRED_VERSION_linux-yocto ?= "6.6%" PREFERRED_VERSION_linux-yocto-rt ?= "6.6%" SDK_NAME = "${DISTRO}-${TCLIBC}-${SDKMACHINE}-${IMAGE_BASENAME}-${TUNE_PKGARCH}-${MACHINE}" SDKPATHINSTALL = "/opt/${DISTRO}/${SDK_VERSION}" DISTRO_EXTRA_RDEPENDS += "${POKY_DEFAULT_EXTRA_RDEPENDS}" DISTRO_EXTRA_RRECOMMENDS += "${POKY_DEFAULT_EXTRA_RRECOMMENDS}" TCLIBCAPPEND = "" PACKAGE_CLASSES ?= "package_rpm" SANITY_TESTED_DISTROS ?= " \ poky-4.3 \n \ poky-5.0 \n \ ubuntu-20.04 \n \ ubuntu-22.04 \n \ ubuntu-23.04 \n \ fedora-38 \n \ fedora-39 \n \ centosstream-8 \n \ debian-11 \n \ debian-12 \n \ opensuseleap-15.4 \n \ almalinux-8.8 \n \ almalinux-9.2 \n \ rocky-9 \n \ " # add poky sanity bbclass INHERIT += "poky-sanity" # QA check settings - a little stricter than the OE-Core defaults # (none currently necessary as we now match OE-Core) #WARN_TO_ERROR_QA = "X" #WARN_QA_remove = "${WARN_TO_ERROR_QA}" #ERROR_QA_append = " ${WARN_TO_ERROR_QA}" require conf/distro/include/poky-world-exclude.inc require conf/distro/include/no-static-libs.inc require conf/distro/include/yocto-uninative.inc require conf/distro/include/security_flags.inc INHERIT += "uninative" BB_SIGNATURE_HANDLER ?= "OEEquivHash" BB_HASHSERVE ??= "auto" POKY_INIT_MANAGER = "sysvinit" INIT_MANAGER ?= "${POKY_INIT_MANAGER}" # We need debug symbols so that SPDX license manifests for the kernel work KERNEL_EXTRA_FEATURES:append = " features/debug/debug-kernel.scc" # Enable creation of SPDX manifests by default INHERIT += "create-spdx"
On peut y observer qu'elle définit pas mal de variables. Entre autres
DISTRO
»,
«DISTRO_NAME
», «DISTRO_VERSION
» etc.
qui permettent d'identifier la distribution. Nous les remplacerons.
SDK_VENDOR
», «SDK_VERSION
», etc.
qui interviennent dans les noms liés au SDK (la chaîne de cross-compilation que nous extrairons dans la séquence III-2).
SANITY_TESTED_DISTROS
» : la
liste des distributions Linux sur lesquelles le build de Yocto a été testé et vérifié. Si votre
distribution n'est pas présente dans cette liste vous avez probablement un warning en
lançant bitbake
.
INIT_MANAGER
» : la méthode
d'initialisation du système une fois le boot du kernel achevé. Il existe trois
possibilités «sysvinit
» l'initialisation traditionnelle System V à
base de scripts shell, «systemd
» l'initialisation généralement
utilisée sur les serveurs et postes de travail, et «mdev-busybox
» une
version simplifiée et allégée de System V.
Lors de la création d'une distro pour un projet client, je
vérifie et rédéfinis si besoin toutes les variables. Ici nous allons
simplement modifier les identifiants «DISTRO_...
».
Nous allons donc définir un fichier de distro personnalisée et
inclure avec la directive «require
»
la distro poky
originale.
Je crée donc un sous-répertoire «conf/distro
› dans mon
layer
[build-qemu]$ mkdir ../../layers/meta-my-layer/conf/distro
Dans ce répertoire j'ajoute un fichier «my-distro.conf
»
contenant :
require conf/distro/poky.conf DISTRO = "my-distro" DISTRO_NAME = "My experimental distro" DISTRO_VERSION = "1.0"
Enfin, il ne faut pas oublier de sélectionner notre distro. Ceci s'obtient dans
le fichier «conf/local.conf
».
Par défaut une ligne «DISTRO ?= "poky"
» est présente un peu avant
le milieu du fichier. Nous pouvons la surcharger en ajoutant au début du fichier la
ligne suivante
DISTRO = "my-distro"
Après recompilation, quand je démarre l'émulateur je vois :
[...] Starting bluetooth: bluetoothd. Starting syslogd/klogd: done * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon ...done. My experimental distro 1.0 mybox ttyAMA0 mybox login: root Password: (linux) root@mybox:~#
Il n'y a plus de messages de warning et le prompt de connexion est précédé des identifiants que nous avons mis dans le fichier de configuration de notre distro.
Nous avons vu dans cette séquence – assez longue – comment
personnaliser notre image en ajoutant des applications dont les
recettes sont livrées avec Poky ou référencées sur le site
Open Embedded Layers Index.
Nous avons également réussi à créer notre propre image, plutôt que de
se limiter à enrichir core-image-base
et même à créer notre
propre distro.
Dans la prochaine séquence, nous verrons comment modifier le comportement d’une application existante, sans toucher aux recettes téléchargées…
Si vous préférez une session de cours interactif, en mode présentiel ou distanciel, n'hésitez pas à vous inscrire à mes formations "Développeur Linux embarqué avec Yocto Project" ou "Yocto Project avancé" .
Ce document est placé sous licence Creative Commons CC BY-NC. Vous pouvez copier son contenu et le réemployer à votre gré pour une utilisation non-commerciale. Vous devez en outre mentionner sa provenance.
Le nom Yocto Project est une marque déposée par la Linux Foundation. Le présent document n'est en aucune façon approuvé par Yocto Project ou la Linux Foundation.