Une clé USB pour les booter vraiment tous
sam. 30 sept. 2017 by MarmotteLorsqu'on bidouille des machines, il arrive que le système ne démarre plus. Que seul le boot loader soit cassé, ou que ce soit le système complet, il est donc important d'avoir à disposition un moyen de démarrer la machine, pour réparer les dégâts.
J'explique ici la manière dont j'ai configuré ma clé USB de boot, qui me permet de démarrer toutes les machines que j'utilise, en utilisant grub, depuis un système Debian. La configuration d'un boot loader étant parfois capricieuse, la méthode expliquée ici n'est peut être pas universelle, mais elle fonctionne pour moi sur des machines très différentes.
Note : Cet article est une mise à jour d'un précédent article.
Différences avec l'article précédent¶
La partition en ext2 ne semble plus être nécessaire avec les versions récentes de grub, je l'ai donc retirée, pour simplifier la procédure initiale et la maintenance. N'avoir qu'une seule partition, en vfat, permet aussi de modifier le contenu depuis une machine sous Windows ou MacOS, ce qui peut être utile pour ceux qui n'ont pas de machine sous Linux disponible.
De plus, le menu du grub est maintenant en grande partie généré dynamiquement. Il nécessite donc beaucoup moins de modifications manuelles, et n'affiche plus que les éléments réellement disponibles.
La configuration dynamique est en partie inspirée du projet Super Grub Disk 2.
Préparation de la clé USB¶
Ma clé USB de 128 Mo ayant cessé de fonctionner, je l'ai remplacée par la suivante, qui propose une capacité de 256 Mo.
Le partitionnement est simple, puisqu'il suffit de créer une unique partition, occupant tout l'espace de la clé USB, formatée en vfat
:
$ sudo cfdisk /dev/sdX
$ sudo mkfs.vfat /dev/sdX1
Où /dev/sdX
correspond à la clé USB.
Note : Il n'est pas nécessaire d'activer le flag boot sur la partition. En effet, contrairement à ce que je pensais lors de la rédaction du précédent article, ce flag n'est pas utilisé par grub.
Installation de grub¶
Il faut tout d'abord installer les paquets binaires nécessaires. Ceux-ci contiennent les fichiers qui seront copiés sur la clé USB lors de l'installation de grub.
$ sudo apt-get install grub-pc-bin grub-efi-amd64-bin
Si ce n'est pas déjà le cas, la partition de la clé USB doit être montée, pour permettre à l'installeur de grub d'y copier les fichiers nécessaires.
$ # Création du répertoire de montage
$ sudo mkdir /mnt/usb
$ sudo mount /dev/sdX1 /mnt/usb
Enfin, il ne reste plus qu'à mettre les targets grub en place sur la clé USB.
$ sudo grub-install -v --no-floppy --boot-directory=/mnt/usb --removable --locales= --fonts= --target=i386-pc /dev/sdX
$ sudo grub-install -v --no-floppy --boot-directory=/mnt/usb --removable --locales= --fonts= --target=x86_64-efi --efi-directory=/mnt/usb --no-uefi-secure-boot
Note : Les paramètres
--locales=
et--fonts=
permettent de n'inclure aucune locale, et aucune police, lors de l'installation. Cela permet de réduire la place occupée par grub sur la clé USB de moitié.Note : Je n'ai pas encore réussi à permettre le démarrage sur un système avec secure boot activé. Pour les machines sur lesquelles j'active le secure boot (Ubuntu propose un noyau signé), je le désactive temporairement pour pouvoir démarrer sur la clé USB.
Configuration de grub¶
Le boot loader installé n'a actuellement pas de fichier de configuration. Il affichera donc juste une invite de commande lors du démarrage, ce qui n'est pas vraiment pratique à utiliser.
Il est possible de définir une configuration, dans un fichier de configuration nommé grub.cfg
, qui sera placé dans le répertoire grub
de la clé USB.
Cette configuration était statique dans le précédent article, mais j'ai récemment trouvé comment la rendre dynamique, ce qui permet de détecter de manière automatique les fichiers ISO, configurations de grub, noyaux Linux...
De cette façon, seuls les éléments présents sont affichés, et il n'est plus nécessaire de mettre à jour la configuration de la clé USB pour chaque machine à démarrer, ni lors de la mise à jour du noyau des machines.
La structure de ma configuration dynamique est la suivante :
for dev in (*); do
# List matching files
filelist=
for file in $dev/pattern $dev/other/pattern; do
if [ -f $file ]; then
filelist="$file $filelist"
fi
done
if [ ! -z $filelist ]; then
probe --set uuid -u $dev
submenu "Autodetected FILETYPE on $dev" $uuid "$filelist" {
set uuid="$2"
set filelist="$3"
# Add an entry for each matching file in the menu
for file in $filelist; do
menuentry 'Entry for file $file' $file $uuid {
set file="$2"
set uuid="$3"
search --no-floppy --fs-uuid --set=root $uuid
# Boot instructions
}
done
}
fi
done
La boucle for dev in (*)
qui englobe la totalité du script permet de parcourir tous les périphériques, partitions, volumes logiques, etc.
La seconde boucle for file in $dev/pattern $dev/other/pattern
permet de chercher des fichiers sur le périphérique en cours de traitement, selon un format de chemin.
Tester l'existence du chemin reste nécessaire, puisque, lorsqu'aucun fichier ne correspond, grub entre quand même dans la boucle, en assignant le pattern dans la variable $file
.
La seule instruction de l'exemple ajoute le nom du fichier trouvé dans une liste, sous forme d'une chaîne de caractères, mais il est parfois nécessaire d'effectuer d'autres vérifications sur le fichier, comme dans le cas d'un fichier ISO.
Le bloc suivant n'est exécuté que si au moins un fichier a été trouvé, ce qui permet d'éviter d'afficher une ligne dans le menu pour chaque périphérique, alors que la plupart ne contiennent pas les fichiers recherchés. Les instructions de ce bloc génèrent un sous-menu, dans lequel une entrée sera créée par fichier trouvé, afin de regrouper les entrées dans le menu par couple périphérique/type. Le scope des variables est différent dans chaque sous-menu et entrée de menu, il est donc nécessaire de les passer en paramètre à chaque niveau.
Enfin, la boucle for file in $filelist
permet de créer une entrée de menu par fichier trouvé.
L'instruction search
est souvent nécessaire, puisqu'elle permet de définir le périphérique sur lequel le démarrage est effectué comme racine, lors de l'exécution de cette entrée de menu.
Enfin, il est nécessaire de charger certains modules de grub pour lui permettre d'accéder à tous les périphériques, dont :
part_msdos
: Accès aux partitions d'un disque utilisant une table de partition MBRpart_gpt
: Accès aux partitions d'un disque utilisant une table de partition GPTlvm
: Accès aux volumes logiques LVM présents sur les partitions du disqueiso9660
: Accès au contenu des fichiers ISOloopback
: Permet le montage de fichiers comme périphériques pour en explorer le contenu
Exemple de configuration¶
A titre d'exemple, voici le fichier de configuration actuel de ma clé USB.
Cette configuration cherche :
- Les images ISO au format casper (le format utilisé par Ubuntu) dans un répertoire
/linux-iso
- Les fichiers de configuration
grub.cfg
placés dans les répertoires/grub
ou/boot/grub
- Les noyaux Linux placés dans le répertoire
/boot
ou à la racine des périphériques
Une clé USB pour les booter tous
Lorsqu'on bidouille des machines, il arrive que le système ne démarre plus. Que seul le boot loader soit cassé, ou que ce soit le système complet, il est donc important d'avoir à disposition un moyen de démarrer la machine, pour réparer les dégâts.
J'explique ici la manière dont j'ai configuré …
read more