URL: https://linuxfr.org/users/pied/journaux/petitboot-sur-arm-le-bon-le-bad-et-le-ugly Title: Petitboot sur ARM, le bon, le bad et le ugly Authors: Pinaraf Date: 2023年11月21日T09:10:10+01:00 License: CC By-SA Tags: petitboot, arm, odroid, firmware, devicetree, bios et linuxbios Score: 47 Oui bon ça va hein, la traduction française elle passe pas pour le titre. Bonjour ! Aujourd'hui, comme évoqué dans des discussions précédentes (et c'est mon deuxième journal avec plusieurs mois de retard), je voudrais vous parler de petitboot, mon bootloader préféré, en me focalisant sur la seule implémentation à laquelle j'ai accès aujourd'hui, avec ses problèmes mineurs et ses problèmes... pas majeurs, mais disons franchement ridicules. On va donc parler de firmware dans le style du BIOS ou de l'UEFI. Mais avant de pouvoir faire ça, un petit rappel des faits est requis. 1) Le BIOS, mais késako ======================= Le BIOS est une invention un peu spéciale de l'IBM PC. Lors de la conception du PC, IBM voulait utiliser du matériel disponible «sur l'étagère» : les premiers PCs étaient un assemblage de composants existants. Problème pour IBM : comment empêcher la création de clones du PC ? La solution : le BIOS. Un composant logiciel intégré sur la carte mère, dont dépendra l'ensemble de la pile logicielle du PC (MS-DOS et ses applications, pour simplifier), et qu'IBM ne diffusera pas aux concurrents. Simple et efficace, non ? Et puis tant qu'à faire, autant y embarquer un interpréteur BASIC pour que la machine serve à quelque chose même sans disquette de système... Le BIOS avait donc à la fois le rôle de bootloader (qui a évolué avec le temps, l'apparition des disques durs, du réseau, des CD-ROM...) et un rôle d'abstraction par dessus le matériel. Par exemple : pas besoin de pilotes pour utiliser un clavier USB sous DOS avec une application de 1980... Comment est-ce possible ? Grâce au BIOS, qui expose une API basique pour interagir avec le clavier, et fait abstraction du contrôleur clavier. De même pour l'accès à un disque dur PATA vs SATA... Bien sûr, IBM n'avait pas anticipé la créativité et les compétences des ingénieurs de Compaq et Phoenix et la création de BIOS compatibles ne dépendant pas d'IBM. (Et leur tentative de rattraper la chose avec le PS/2 et son MCA n'a heureusement pas réussi) Les systèmes d'exploitation «modernes» n'ont pas une telle dépendance au BIOS. Ils ont des pilotes pour gérer eux-même l'USB, le stockage... avec des bien meilleures performances. Mais pour cela, ils doivent être capables de découvrir le matériel. Et c'est là qu'intervient un rôle ajouté au BIOS, ou plutôt en parallèle du BIOS : la description du matériel, avec en particulier la norme ACPI. (Je sais c'est simplifié, il y a eu aussi l'ISAPnP, le concept de PnP intégré à PCI et à l'USB... mais c'est pas le but de ce journal). Donc en résumé : deux rôles pour le firmware, bootloader et description du matériel. Notez bien cela, nous y reviendrons. 2) Des alternatives au BIOS/UEFI ================================ Alors il faut bien reconnaître, ça ne court pas les cartes mères. Il fut un temps où l'alternative la plus répandue était OpenFirmware, utilisé sur les machines SPARC, POWER, certains ARM... Pendant quelques années c'était même un standard IEEE, mais il est «rétracté» depuis. Lors de la mise en place de l'UEFI sur les PCs, des débats avaient eu lieu vantant cette solution, mais les chevaliers du NIH ne l'ont pas entendu de cette oreille. Avec la fin d'OpenFirmware, une autre solution était nécessaire sur les machines OpenPower, et cette solution a été appelée OPAL, OpenPower Abstraction Layer. Avec OPAL, le boot est assez simple (après x étapes trop bas niveau pour ce journal) : il y a deux parties, skiboot avec un ensemble de services de runtime utilisables par l'OS, et skiroot le bootloader, composé d'un noyau Linux et d'un initramfs contenant Petitboot. Petitboot suit une idée simple elle aussi, similaire à l'idée de LinuxBIOS : puisque le firmware doit gérer le matériel, des systèmes de fichiers, du réseau... autant prendre un noyau complet, un système allégé, et utiliser ce dernier pour aller chercher un noyau, le mettre en mémoire comme il faut et faire un goto, avec l'appel système kexec(). Évidemment, il y a aussi les alternatives libres pour PC, mais avec les processeurs et chipsets modernes le travail est devenu assez difficile, surtout si l'on veut quelque chose d'entièrement libre. On peut donc citer les coreboot (ex-LinuxBIOS, qui reprenait déjà en 2001 l'idée de mettre un noyau Linux dans le firmware), Libreboot (version sans blob de coreboot), LinuxBoot (dérivé de NERF, qui élimine toute une partie de l'EFI pour la remplacer par un noyau Linux)... 3) L'absence de firmware, ça donne quoi ======================================= Nous avons parlé du firmware, maintenant parlons de l'anti-firmware, avec le désastre des cartes ARM. On va prendre une distribution spécialisée ARM pour illustrer le problème, Armbian. Direction armbian.com, section téléchargement. Et il faut choisir la carte que l'on a, et on télécharge une image spécialisée pour cette carte. J'insiste. Une image spécialisée. Parce qu'il faut avoir dans cette image le bootloader compatible avec la carte, les fichiers DTB (Device Tree Blob) décrivant la carte... C'est une calamité. Et ça, c'est pour les fabricants qui jouent le jeu, parce que si vous tombez sur une machine avec un SoC mediatek, vous avez un noyau d'il y a X années patché dégueulassement et démerdez-vous... Microsoft, en proposant Windows pour ARM64, refuse cette situation (normal, ils ne veulent pas qu'on touche à leur noyau) et exige la présence d'un UEFI pour Windows, permettant donc la mise en place d'une image unique pour l'ensemble des cartes ARM compatibles. J'ai suffisamment soupé d'UEFI et de ses bugs pour ne pas en vouloir plus sur mes machines, mais il faut bien reconnaître que l'absence de firmware n'est pas une solution acceptable (surtout quand on pense aux autres OS qui auraient un travail colossal à faire pour supporter l'armée de cartes ARM sur le marché). D'autant plus quand on rencontre des bugs avec le bootloader et qu'on se retrouve sans solution pour comprendre ce qu'il se passe... (non, le port série n'est pas une solution, ça fait disparaitre le bug dans mon cas, tristesse) Pour les plus curieux, je vous invite à regarder à quoi ressemble un fichier DeviceTree. Je vais prendre en exemple une de mes machines ARM64, à base de puce Amlogic S905X3. Cette machine a heureusement un DTS (Device Tree Source) dans le noyau, donc elle est officiellement supportée «upstream» comme on dit. https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts On observe une description de l'ensemble des composants, le ventilateur, les leds, les régulateurs de tension, les différents bus... Parce que la machine ne dispose d'aucune solution d'énumération du matériel. Et bien sûr, impossible d'aller au hasard sur les GPIO du SoC pour voir ce qui est branché où, c'est un coup à, au mieux, éteindre la machine soudainement (et au pire, à la détruire). Que ce soit clair : ce fichier DTS n'est pas spécifique à un SoC, il est spécifique à une implémentation d'un SoC ! Les odroid C4 et HC4, bien qu'extrêmement proches et avec le même SoC, n'ont pas le même DeviceTree, et il est probable que booter l'un avec le DT de l'autre ne marche pas du tout. 4) Et une exception dans le chaos ? =================================== Au moins un fabricant de cartes ARM a compris qu'embarquer un firmware sur ses cartes était une solution simple pour améliorer beaucoup de choses. Ou alors pour simplifier son travail, je ne sais pas trop leur motivation. Il s'agit de hardkernel et de ses cartes odroid. L'intégration par défaut de petitboot est «relativement» récente, avec une annonce initiale en 2019 et une préinstallation qui a commencé dans les mois qui ont suivi. Du coup, commençons enfin le sujet de ce journal, avec le bon. Prenons mon serveur installé avec petitboot, et faisons un fdisk -l. ``` # fdisk -l /dev/nvme0n1 Disk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors Disk model: Samsung SSD 980 1TB Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 16384 bytes / 131072 bytes Disklabel type: dos Disk identifier: 0xc7716abe Device Boot Start End Sectors Size Id Type /dev/nvme0n1p1 * 2048 999423 997376 487M 83 Linux /dev/nvme0n1p2 999424 1953523711 1952524288 931G 8e Linux LVM ``` Pas de partition FAT32. Une simple partition ext4 contenant /boot, et c'est réglé. Contrairement aux systèmes UEFI qui imposent une partition ESP à un format compris par l'UEFI, donc dans 99,9999% des cas en FAT. J'eus pu faire avec une unique partition / et pas un /boot, mais je préfère mettre tout ce qui peut l'être en LVM. Bien sûr, ce n'est pas grand chose, la partition FAT n'a jamais tué personne. Alors continuons avec un exemple très concrêt de ce que m'apporte Petitboot ici. Pour installer ma debian, je n'ai pas eu besoin de clé USB ou de carte SD à écrire sur mon PC. Non. J'ai pris ma carte ARM, j'ai vissé un disque NVMe, branché un écran, un clavier, un RJ45, et c'est tout (bon et l'alimentation hein, c'est pas de la magie). Petitboot est apparu à l'écran. Je ferme l'écran de boot pour obtenir un shell, et je lance une commande fournie par hardkernel, netboot_default. Cette commande ajoute automatiquement des entrées au boot pour aller chercher l'installeur debian et l'installeur ubuntu en HTTP au démarrage. Je démarre l'installeur debian comme ça, j'installe mon système... et aucune clé USB ou carte SD à écrire. Très, très, très confortable. Bien sûr, petitboot lui-même est super pratique : si vous cassez votre système, vous avez un shell, un noyau et un espace utilisateur connus, à partir desquels vous pouvez monter votre système et faire les réparations dont vous avez besoin. Quelques photos du menu initial, du shell, et le menu une fois les entrées de netboot chargées et une carte SD insérée...    5) Le bad ========= Hardkernel ne fournit pas de méthode ou de documentation pour reproduire l'image Petitboot. C'est plusieurs fois dommage : cela ne permet pas de bidouiller facilement le système, de vérifier son contenu... Et c'est même en violation des licences des composants de Petitboot, ça risque de leur retomber méchamment dessus. Pour ma part, ce point m'embête également pour régler un autre problème qui me semble vraiment "bad" pour le coup : pourquoi des utilitaires disque à mes yeux basiques ne sont pas inclus ? Cela fait presque 20 ans que j'installe mes machines avec du LVM, je sais que les installeurs ne mettent pas ça assez en avant, mais le gain en vaut largement la peine. Et petitboot le gère, mais la version de hardkernel oublie d'embarquer le binaire... À la croisée entre ces deux problèmes, la validation du système et les disques : cryptsetup n'est pas pris en charge. Et c'est dommage, il serait possible d'avoir un disque intégralement chiffré, avec une passphrase demandée au boot, et transmise au noyau démarré pour qu'elle n'ait pas à être saisie deux fois. Enfin, un dernier bad : dropbear n'est pas présent. Pour des machines sans affichage, cela simplifierait énormément les choses... Mais à nouveau, oubli bien dommage de leur part. 6) Le ugly ========== Vous noterez que je n'ai parlé que d'une des facettes principales du firmware (le bootloader) et un peu survolé la partie «outils pour diagnostiquer un problème». Les plus attentifs d'entre vous auront noté que je n'ai pas parlé de la description du matériel et sa transmission au système démarré. Et là, on entre dans le franchement ugly. ``` # ls /boot/*`uname -r` /boot/config-6.2.0-odroid-arm64 /boot/dtb-6.2.0-odroid-arm64 /boot/initrd.img-6.2.0-odroid-arm64 /boot/System.map-6.2.0-odroid-arm64 /boot/vmlinuz-6.2.0-odroid-arm64 ``` J'ai besoin d'un fichier dtb encore ? Mais pourquoi ! Pourquoi pourquoi pourquoi ! Rendez-vous compte, le firmware a déjà un DeviceTree ou équivalent pour booter son Linux. Et il fonctionne très bien. Alors pourquoi ? Vous étiez à deux doigts de pouvoir avoir des systèmes génériques, pire encore, à quatre doigts d'avoir une interface de configuration pour vos accessoires qui activerait au boot les bons morceaux de dtb... Et vous avez gâché cette opportunité. Et comme vous ne donnez pas le code source, impossible de rattraper votre bêtise crasse. 7) The conclusion ================= Je reste heureux de mes machines Petitboot, et il est hors de question que je retourne en arrière là dessus. Le gain en confort est indéniable, malgré les problèmes évoqués. De plus, ces problèmes ne sont pas insurmontables, et sont des problèmes d'implémentation, pas des problèmes fondamentaux sur le fonctionnement de Petitboot. Puis qui sait, avec un peu de chance, la future machine OpenPower 10 de Raptor Computing ne sera pas trop onéreuse... (ok, beaucoup beaucoup beaucoup beaucoup de chance) J'entends par contre que cette solution ne soit pas optimale pour les plus petits OS qui n'ont pas nécessairement les moyens de développer une solution de boot supplémentaire spécifique, démarrable en kexec(). On pourrait imaginer pour ces cas là un kexec() vers un environnement UEFI éventuellement... (ou juste contribuer aux projets concernés, promis quand j'aurai du temps, mais pour le moment je rédige un journal linuxfr)