28 liens privés
objcopy below image base no efi bootable devices
Du jour au lendemain, l'UEFI qui veut plus démarrer mon système Debian…
Ma configuration :
- Un noyau unifié EFI - kernel efi stub;
- Plus de grub installé depuis 3~4 ans 👍
Problème :
- Au démarrage, peu importe l'entrée UEFI sélectionnée, le résultat restait : No bootable devices found…
Comportement attendu :
- Démarrage de Linux;
- Prompt pour entrer ma passphrase Luks;
- Fin du démarrage de Debian et atterrissage dans tty1 👍
Version courte
J'ai dû mettre à jour ma commande ''objcopy'' afin qu'elle tienne compte de "l'adresse" du fichier de base et par la même occasion de la taille des différentes sections ajoutées. Cette nouvelle commande fonctionne :
osrel_offs=$(objdump -h "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" | awk 'NF==7 {size=strtonum("0x"$3); offset=strtonum("0x"$4)} END {print size + offset}')
cmdline_offs=$((osrel_offs + $(stat -Lc%s "/usr/lib/os-release")))
linux_offs=$((cmdline_offs + $(stat -Lc%s "/proc/cmdline")))
initrd_offs=$((linux_offs + $(stat -Lc%s "/boot/vmlinuz-6.3.0-1-amd64")))
objcopy \
--add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=$(printf 0x%x $osrel_offs) \
--add-section .cmdline="/proc/cmdline" --change-section-vma .cmdline=$(printf 0x%x $cmdline_offs) \
--add-section .linux="/boot/vmlinuz-6.3.0-1-amd64" --change-section-vma .linux=$(printf 0x%x $linux_offs) \
--add-section .initrd="/boot/initrd.img-6.3.0-1-amd64" --change-section-vma .initrd=$(printf 0x%x $initrd_offs) \
/usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/efi/EFI/debian/debian.6.3.0-1.efi
La dernière version de cette commande est présente dans mon script create-efi-kernel qui s'occupe également de "plein" d'autres trucs afin d'avoir automatiquement les noyaux unifiés à partir des noyaux Linux disponibles, d'ajouter les entrées efi correspondantes, nettoyées les anciennes,…
Version longue
Ma précédente commande avec des valeurs d'adresses fixes qui fonctionnait jusqu'à systemd ≤ 253 :
objcopy \
--add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \
--add-section .cmdline="/proc/cmdline" --change-section-vma .cmdline=0x30000 \
--add-section .linux="/boot/vmlinuz-6.3.0-1-amd64" --change-section-vma .linux=0x2000000 \
--add-section .initrd="/boot/initrd.img-6.3.0-1-amd64" --change-section-vma .initrd=0x3000000 \
/usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/efi/EFI/debian/debian.6.3.0-1.efi
Mais qui pose problème à partir de systemd 254, en m'indiquant des "erreurs" :
objcopy: /boot/efi/EFI/debian/debian.efi:.osrel: section below image base
objcopy: /boot/efi/EFI/debian/debian.efi:.cmdline: section below image base
objcopy: /boot/efi/EFI/debian/debian.efi:.linux: section below image base
objcopy: /boot/efi/EFI/debian/debian.efi:.initrd: section below image base
Ça tient plus du warning parce que la commande se termine correctement… (code retour = 0 🤦).
Et ça me donne un noyau "debian.efi" qui fait la même taille que d'habitude…
➡️ Je vais donc tenter de récupérer le fichier /usr/lib/systemd/boot/efi/linuxx64.efi.stub pour chaque version de systemd (celle qui fonctionnait et la nouvelle) pour comparaison + le détails du cheminement pour y arriver.
- Vérifier le paquet qui contient le fichier recherché :
apt-file search /usr/lib/systemd/boot/efi/linuxx64.efi.stub
systemd: /usr/lib/systemd/boot/efi/linuxx64.efi.stub
systemd-boot-efi: /usr/lib/systemd/boot/efi/linuxx64.efi.stub
- ➡️ Dans les récentes versions de systemd, le "boot-efi" a été envoyé dans un paquet dédié, on va donc se focaliser sur systemd-boot-efi.
- Vérifier les version de systemd-boot-efi disponible :
apt-cache policy systemd-boot-efi
systemd-boot-efi:
Installed: 254~rc2-3
Candidate: 254~rc2-3
Version table:
*** 254~rc2-3 500
500 http://deb.debian.org/debian sid/main amd64 Packages
500 http://deb.debian.org/debian unstable/main amd64 Packages
100 /var/lib/dpkg/status
253.5-1 100
-1 http://deb.debian.org/debian trixie/main amd64 Packages
…
- ➡️ La version actuellement installée, 254~rc2-3 c'est celle qui ne fonctionne pas. On va donc tenter de récupérer la version disponible dans Debian Trixie.
- Télécharger la version 253 et extraire le fichier linuxx64.efi.stub de ce premier paquet :
aptitude download systemd-boot-efi=253.5-1
ar p systemd-boot-efi_253.5-1_amd64.deb data.tar.xz | tar xJ -C . --strip-components=6 ./usr/lib/systemd/boot/efi/linuxx64.efi.stub
mv linuxx64.efi.stub linuxx64.efi.stub.253
- Idem pour la version 254 :
aptitude download systemd-boot-efi/unstable
ar p systemd-boot-efi_254\~rc2-3_amd64.deb data.tar.xz | tar xJ -C . --strip-components=6 ./usr/lib/systemd/boot/efi/linuxx64.efi.stub
mv linuxx64.efi.stub linuxx64.efi.stub.254
- Et maintenant si je compare la "taille + offset" des deux fichiers linuxx64.efi.stub.253 et linuxx64.efi.stub.254 :
objdump -h "/tmp/linuxx64.efi.stub.253" | awk 'NF==7 {size=strtonum("0x"$3); offset=strtonum("0x"$4)} END {print size + offset}'
82187
objdump -h "/tmp/linuxx64.efi.stub.254" | awk 'NF==7 {size=strtonum("0x"$3); offset=strtonum("0x"$4)} END {print size + offset}'
5603209336
- Ah bah oui… 😅 82187 vs 5603209336 ! Le message d'objcopy est donc cohérent.
En vrai, ci-dessus c'est quand même une version condensée/expliquée du problème… Le cheminement pour arriver jusque là a été un poil plus long et "stressant"…
- Plusieurs passages en mode rescue.
- La crainte d'un défaut de l'UEFI (on est pas à l'abri sur les Dell…).
- Recherche de bug/documentation/… pas très fructueuse (une recherche "noyau unifié + debian" c'est pas la panacée, heureusement il y a ArchLinux et Gentoo).
- Même le manuel Debian qui évoque un assemblage de ce type de noyau utilise potentiellement des valeurs d'adresses trop petites 😀
- Vérification des derniers paquets mis à jour (en regardant la fin du fichier /var/log/apt/history.log).
- Via le mode rescue, un petit downgrade de tous les récents paquets systemd qui ont été mis à jour et là j'arrive bien à générer des noyaux fonctionnels ! Début de piste…
- Maintenant que j'ai accès à mon système la recherche d'info sur le net et les tentatives de génération de noyaux sont plus simples ! J'augmente au fur et à mesure la valeur de chaque adresse jusqu'à ne plus avoir ce warning. Oh "miracle", j'ai un noyau généré sans "erreurs" ! Je tente le boot et obtiens un message d'erreur différent "kernel not found". Ok, donc lien de cause à effet confirmé :)
- Délivrance avec le wiki ArchLinux et la génération manuelle des noyaux unifiés qui calcule la taille de l'image et de chaque sections (la solution détaillée ci-dessus) 👌
Conséquences
- J'ai perdu un peu de temps…
- Les adresses utilisées par chaque section sont maintenant cohérentes et moins sujettes à problème 🤞
- Je conserve maintenant quelques versions des noyaux unifiés précédents. Comme ça si les derniers plantent, je peux toujours m'ajouter manuellement une entrée EFI qui pointe vers un précédent noyau (théoriquement) fonctionnel et "retrouver" mon système ! 🤞🤞
- TODO: Il faut que j'investigue sur Dracut et la possibilité d'avoir des noyaux signés et ainsi pouvoir activer le SecureBoot…
- J'ai "appris" la possibilité d'ajouter un splash screen dans un noyau unifié. Bon par contre, c'est forcément en bmp (d'après le peu de tests que j'ai réalisé) donc ça alourdit quand même le noyau pour un intérêt limité… J'ai déjà pas de gestionnaire de session, alors le fait de voir un logo Debian pendant deux secondes au démarrage… ¯_(ツ)_/¯