Livraison Buildroot reproductible : de l’image amorçable au dossier de version
Une image Buildroot devient un livrable lorsqu’un autre ingénieur peut la reconstruire, identifier précisément son contenu et remettre la cible en état sans dépendre du poste du développeur initial. Pour une passerelle ou un terminal opérateur, cela implique de gérer les sources, la configuration, l’environnement de compilation, l’organisation de l’image et les preuves de réception comme une seule version. Une carte SD qui démarre n’est qu’un des résultats de ce processus.
Définir « reproductible » dans les conditions de livraison
Fixez deux critères de réception distincts. Une version reconstructible dispose d’une procédure complète permettant d’obtenir les fonctions prévues à partir d’entrées archivées. Une version reproductible octet pour octet produit en plus des octets identiques pour un ensemble d’artefacts explicitement désignés. Ce second critère suit la définition du projet Reproducible Builds ; il exige des preuves de comparaison, et non une case cochée dans la configuration.
Nommez les artefacts : noyau, arbres de périphériques, système de fichiers racine, chargeur d’amorçage et, éventuellement, image complète du support. Précisez si les conteneurs signés et la personnalisation en fabrication font partie du périmètre de comparaison. L’identité propre à chaque appareil doit être provisionnée séparément de l’image générique ; sinon, les appareils doivent naturellement présenter des octets différents. Conservez les clés privées de signature hors du paquet de sources et des journaux de compilation.

Figer toutes les entrées
Établissez un manifeste de version avant de générer une image de production. Il doit identifier la révision de Buildroot, celle de la configuration produit, les commits applicatifs, les révisions du noyau et du chargeur, l’empreinte de la chaîne de compilation externe éventuelle et chaque correctif fournisseur. Ajoutez la révision de la carte et la variante de stockage effectivement montée. « Le SDK fournisseur » est trop vague lorsque plusieurs archives portent le même nom.
Placez les adaptations produit dans une arborescence BR2_EXTERNAL versionnée : defconfig, configuration du noyau, modifications des arbres de périphériques, fichiers de surcharge, recettes de paquets et scripts de génération d’image. Archivez la .config résolue comme preuve de version. Livrez les fichiers générés dans output/images ; l’arborescence intermédiaire target n’est pas un système racine déployable avec ses permissions finales et la gestion définitive des fichiers de périphérique. Ces mécanismes sont décrits dans le manuel Buildroot.
Pour chaque binaire propriétaire, consignez son fournisseur, sa version, sa somme de contrôle, l’ABI cible et les conditions de redistribution. Un binaire redistribuable peut constituer une entrée figée même sans accès aux sources, mais cette limite doit figurer dans la description de livraison. Désignez un responsable de la disponibilité des téléchargements plutôt que de supposer qu’une URL amont restera accessible pendant toute la durée de service du produit.
Permettre de reconstituer l’environnement et les sources
Documentez l’environnement Linux de compilation, l’empreinte de l’image du conteneur ou de la machine virtuelle, les paquets de l’hôte, l’architecture et les ressources nécessaires. Utilisez des chemins absolus stables pour les sources et les sorties. L’option BR2_REPRODUCIBLE reste expérimentale ; son aide de configuration décrit les contraintes liées aux chemins et les paquets qui peuvent encore ne pas être reproductibles. Consultez l’aide de la version figée sans présumer qu’une branche plus récente se comporte de façon identique.
Conservez un cache de sources approuvé et vérifiez les empreintes des téléchargements. Le cache facilite la reconstruction, mais n’authentifie pas les sources à lui seul. Après récupération des dépendances, lancez une reconstruction distincte avec le réseau sortant désactivé. Si elle échoue, relevez précisément l’entrée manquante plutôt que d’autoriser discrètement un paquet à télécharger une dépendance non répertoriée pendant la compilation.
L’exemple suivant esquisse une tâche de livraison. Les chemins et product_defconfig sont définis par le projet ; activez la reproductibilité dans cette defconfig enregistrée dans le dépôt. Exécutez la tâche avec un utilisateur de compilation non privilégié, dans un environnement propre.
export BR=/work/buildroot
export EXT=/work/product
export OUT=/work/out
export LC_ALL=C TZ=UTC
export SOURCE_DATE_EPOCH="$(git -C "$EXT" log -1 --format=%ct)"
make -C "$BR" O="$OUT" BR2_EXTERNAL="$EXT" product_defconfig
make -C "$BR" O="$OUT" source
make -C "$BR" O="$OUT"
make -C "$BR" O="$OUT" legal-info
SOURCE_DATE_EPOCH fournit aux outils compatibles un horodatage stable lié aux sources. Cette variable ne rend pas déterministes des scripts arbitraires. Vérifiez sa propagation dans la version Buildroot retenue et recherchez l’utilisation de l’heure courante dans les scripts personnalisés. La documentation SOURCE_DATE_EPOCH en définit la sémantique.
Comparer deux compilations propres et indépendantes
Exécutez la même procédure dans deux environnements neufs, avec les mêmes chemins documentés. Préservez les deux sorties avant le début de la tâche suivante. Comparez d’abord la liste exacte des artefacts et leurs sommes de contrôle. Pour un produit d’exemple qui génère ces deux fichiers :
cd /work/out/images
sha256sum Image rootfs.squashfs > /work/release/SHA256SUMS
Créez préalablement /work/release et remplacez cette liste par le manifeste réel, y compris les arbres de périphériques et composants d’amorçage. Une racine identique ne prouve pas que l’image complète du support est identique. En cas d’écart, utilisez diffoscope pour examiner les fichiers incorporés, les métadonnées et les différences d’archives ; conservez le rapport.
Classez les différences avant de modifier les options. Les horodatages du noyau, les noms d’utilisateur et d’hôte, les chemins de débogage et les clés de signature de modules générées automatiquement sont des sources de variation recensées dans le guide de reproductibilité du noyau. Les UUID de systèmes de fichiers, horodatages de génération d’image, listes de fichiers non triées et scripts de version applicatifs constituent d’autres pistes. Maintenez les exigences de sécurité lorsque vous définissez et testez une éventuelle étape de signature séparée.
Tester la version livrée, pas seulement le résultat du compilateur
| Test | Preuves à conserver | Décision de livraison |
|---|---|---|
| Deux compilations propres | Empreintes des entrées, liste des artefacts et rapport de comparaison | Tous les octets du périmètre concordent, sinon la version n’est pas qualifiée de reproductible octet pour octet |
| Reconstruction hors ligne | Journal de tâche sans réseau et manifeste du cache | Aucun téléchargement non déclaré n’est nécessaire |
| Démarrage à froid de chaque révision matérielle | Journal série d’amorçage et identification du matériel | Arbre de périphériques, stockage et démarrage applicatif corrects |
| Mise à jour et restauration | Journaux de changement de version, d’interruption de mise à jour et de restauration | Retour à l’état utilisable documenté |
| Migration de configuration | Anciens et nouveaux schémas, paramètres conservés | Mise à jour et retour arrière pris en charge préservent le comportement prévu |
| Image de fabrication | Procédure de programmation, vérification des sommes et audit des identités | Bonne image installée sans duplication des secrets propres aux appareils |
Définissez avec cette matrice des limites produit mesurables : point final de mesure du démarrage, consommation mémoire maximale, marge de stockage, comportement réseau et reprise par chien de garde. Déduisez les valeurs numériques des exigences réelles. Cet article décrit un plan de validation, pas des résultats mesurés sur une carte particulière.
Échecs fréquents de transfert et moyens de les isoler
- La compilation propre échoue, celle du développeur réussit : vérifiez les substitutions locales de sources, les correctifs non enregistrés et les outils installés sur l’hôte. Reproduisez dans l’environnement archivé avant de changer les dépendances.
- Un paquet retiré reste dans l’image : repartez d’une arborescence de sortie neuve. Une sortie incrémentale de développement constitue une mauvaise référence de livraison après modification de configuration.
- L’application ne démarre que sur une carte : comparez révision matérielle, arbre de périphériques, binaires de firmware et organisation du stockage avant d’incriminer Buildroot.
- Les images concordent mais la restauration échoue : examinez la sélection d’amorçage, les décalages des partitions et les instructions de restauration. La reproductibilité ne valide pas une procédure de programmation.
- Le dossier de licences paraît complet : examinez les avertissements de
legal-info/READMEet les éléments manquants. La collecte de Buildroot alimente une revue de conformité ; elle ne constitue pas une validation juridique automatique.
Livrer un dossier de version utilisable par un autre ingénieur
Préparez un README indiquant un point d’entrée de compilation pris en charge, le manifeste, les sommes de contrôle, les instructions d’accès aux sources, la configuration, les images, les notes de version, les preuves de test et la procédure de restauration. Consignez les limites connues, la compatibilité des mises à jour et la responsabilité des futures corrections de sécurité. Vérifiez le dossier au cours d’un exercice de transfert sans accès au poste initial.
Pour définir le périmètre, le service de diagnostic firmware et BSP d’Obeita concerne l’intégration de l’amorçage, du noyau et du système racine. Le projet livré de terminal embarqué RK3566 fournit un contexte de plateforme apparenté. Ce cas ne prouve pas que le processus de reproductibilité décrit ici a été réalisé ou validé sur cette plateforme.