Outils pour utilisateurs

Outils du site


expert:grub2

Grub2, le chargeur d'amorçage version 2

Grub est le chargeur d'amorçage de choix sous GNU-Linux, et même si des alternatives existent grub reste dominant. Alors quelle est la raison d'être de Grub2 ?

Réécriture complète du code

Le code de Grub “legacy” est, d'après l'équipe de développeurs qui le maintien, difficile à maintenir. Il est trop complexe, souffre d'erreurs de design qui ne sont pas rattrapables pour cause de rétro-compatibilité. Ce code est toujours maintenu, mais il n'y aura plus d'ajout de nouvelles fonctionnalités à Grub premier du nom, l'avenir est à Grub2.
Le code de Grub2 a fait l'objet d'une réécriture complète, il part sur de nouvelles bases fortes de l'expérience de Grub “legacy”.

Le design de Grub2 est modulaire, l'installation est divisée en plusieurs modules qui sont destinés à différentes architectures et plateformes, avec une base commune.

Au cœur du fonctionnement de Grub2 on trouve l'image amorçable « boot.img » et le mini-initrd “core.img”, celui-ci est suffisamment petit pour être implantée entre le secteur d'amorçage du disque et le début de la première partition, ce qui rend possible de nombreuses utilisations avec des multiboot, des systèmes non-GNU/Linux, et des partitionnements utilisant raid et/ou lvm. Cette image supporte également le chargement de modules de manière dynamique, par exemple raid ou lvm, rendant disponible les volumes de ce type dès le menu Grub.

La configuration est également modulaire, basée sur des scripts entièrement modifiables. Il suffit de créer un script personnel basé sur les modèles fournis, de le déposer dans le répertoire correspondant (exp: /etc/grub.d/), et de mettre à jour le fichier /boot/grub/grub.cfg (le remplaçant de “menu.lst”). Grub2 est également esthétiquement plus réussi que son prédécesseur, il supporte des images de plus haute résolution, et même au stade expérimental la vidéo. (voir http://grub.gibibit.com/ pour un exemple des travaux en cours sur le menu graphique). Grub2 propose également un environnement “shell” (console) développé, avec notamment des fonctions de recherche, support des boucles, il est scriptable, chaînable, supporte le système de fichier ext4 et ne fait pas peur aux enfants: convaincus ? Voyons ça plus en détail.

J'utilise “Grub legacy” pour l'ancien grub, et “Grub2” pour celui dont il est question ici. Debian et Ubuntu sont les systèmes de référence pour cette présentation.

Un signe $ précède les commandes qui ne nécessitent pas de droits administrateur ; un signe # précède celles qui nécessitent des droits administrateur (ces signes ne font PAS partie des commandes). Les lignes qui ne commencent pas par un signe $ ou # correspondent au résultat de la commande précédente.
Les touches utilisées sont indiquées entre crochets, exemple [ctrl] pour la touche “contrôle”

Installation, remplacement de grub-legacy

Prenons l'exemple de Debian, où Grub2 est proposé à l'installation, mais grub “legacy” est encore le choix par défaut. L'installation s'effectue avec le gestionnaire de paquets habituel, il faut juste prendre soin d'installer le paquet qui correspond à l'architecture de la machine: “grub-pc” pour une machine de type “pc” standard, x86 ou x86-64 (amd64).

Lors de l'installation grub “legacy” ne sera pas effacé du secteur d'amorçage (MBR) du disque, grub2 sera “chaîné” à partir du grub déjà existant, pour vérifier que tout fonctionne correctement. Au démarrage suivant il faudra choisir dans le menu grub habituel l'entrée commençant par “chainload into grub2 on …”.

Si tout se passe bien, il est temps de totalement remplacer grub “legacy” par grub2, en exécutant en root la commande:

# upgrade-from-grub-legacy

Après cela grub2 sera installé dans le secteur d'amorçage, et le fichier /boot/grub/grub.cfg prendra le relai de /boot/grub/menu.lst. Ce dernier reste présent pour servir de référence, mais tout à fait être supprimé par la suite.

Sur certaines distribution (testé Ubuntu Hardy) la procédure est un peu différente, le chaînage avec le menu.lst est également proposé, mais pour basculer sur grub2 définitivement il faut simplement l'installer sur le mbr avec:

# grub-install --recheck "(hd0)"
# update-grub2

À partir d'Ubuntu Intrepid le script “upgrade-from-grub-legacy” est également présent.

Premier contact avec la configuration

Pour grub “legacy”, la configuration consistait à retoucher les entrées du fichier “menu.lst” directement, dans de rares cas à modifier le fichier /boot/grub/device.map où sont notés les correspondances entre les disques tels que détectés, et leurs notations pour grub.

Avec grub2 on n'édite pas directement le fichier grub.cfg, mais on intervient sur un ensemble de fichiers de configuration qui seront “sourcés” au moment de la génération du grub.cfg. Toute modification du grub.cfg faite directement sera écrasée très rapidement lors d'un appel à “update-grub” ou “grub-mkconfig”, à éviter donc.

La notation des partitions a évolué, Grub2 numérote les disques à partir de “0” (zero) comme grub “legacy”, mais les partitions à partir de “1”. Donc (hd0,0) pour grub “legacy” devient (hd0,1) avec Grub2 (première partition du premier disque).
Les versions récentes de grub prennent également en charge d'autres formats de tables de partitions que le “classique” dos (comme “gpt”), pour refléter cela la numérotation de vos partitions pourra être de la forme (hd0,msdos1) pour la première partition du premier disque dur.

Les fichiers de configuration sur lesquels on peut intervenir sont:

/ETC/DEFAULT/GRUB

# Ce fichier est sourcé par update-grub ou grub-mkconfig, et ses variables sont propagées
# aux fichiers "fils" dans /etc/grub.d.

# Entrée choisi automatiquement par défaut, "0" = première entrée du fichier grub.cfg .
GRUB_DEFAULT=0

# Durée avant exécution du choix par défaut.
GRUB_TIMEOUT=4

# Reconnaissance de la distribution.
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`

# Chargement des modules additionnels, ici RAID, afin que ces volumes soient disponibles dès le
# menu grub. Indispensable pour des partitions /boot ou / (root) sur raid.
GRUB_PRELOAD_MODULES="raid mdraid"

# Options supplémentaires à passer au noyau (resume=/dev/sda2 ,
# acpi=off...). Concerne aussi les entrées "recovery mode"
GRUB_CMDLINE_LINUX="acpi=off"

# Options supplémentaires à passer au noyau, ne concerne QUE les entrées par défaut,pas
# les entrées "recovery"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

# Décommenter pour inhiber le terminal graphique et forcer un terminal texte
# (grub-pc seulement).
#GRUB_TERMINAL=console

# Résolution et type du terminal graphique (défaut 640x480, gfxgrub). Si une liste de résolution est
# donnée, elles serviront d'alternatives de secours en cas d'impossibilité d'utiliser la principale.
GRUB_GFXMODE="1440x900x24 800x600x24 640x480"
GRUB_TERMINAL=gfxterm
GRUB_GFXPAYLOAD_LINUX="keep"

# Image de fond pour le menu grub
GRUB_BACKGROUND=/boot/grub/mon_image.jpg

# Décommenter pour empêcher l'usage des UUID "root=UUID=xxx" dans grub.cfg .
#GRUB_DISABLE_LINUX_UUID=true

Les commentaires devraient suffirent à rendre compréhensible les variables courantes, celles plus spécifiques à grub2:

  • GRUB_PRELOAD_MODULES= Cette variable permet d'indiquer à grub2 de charger des modules additionnels, par exemple raid, lvm, video … Ces modules seront ajoutés à l'image de démarrage /boot/grub/core.img qui agit à la manière d'un initrd (Initial Ram Disk) minimal.

Concernant les options spécifiques au système de fichier, elles devraient être détectées correctement par grub2 grâce à la commande “grub-probe”. Si vous voulez vous assurer que c'est le cas, vous pouvez faire une vérification avec:

# grub-probe -d /dev/sda1 --target=fs_uuid

Ici on vérifie la détection de l'attribue UUID de la partition racine sda1, à comparer avec le résultat de:

$ ls -l /dev/disk/by-uuid/ | grep sda1

pour s'assurer que c'est le bon UUID qui est détecté.
Plus intéressant, contrôlons que grub2 détecte correctement notre volume raid /dev/md0, sur lequel est installé la racine du système, et chargera les modules nécessaires:

# grub-probe -d /dev/md0 -tabstraction

Ici on utilise la forme courte de “--target” qui est “-t”, pour vérifier la reconnaissance de la couche d'abstraction du système de fichier (le raid). La réponse devrait être “raid mdraid” dans ce cas, ce qui correspond aux modules à inclure dans le core.img et à charger par grub2.

Les paramètres possibles à tester sont “fs, fs_uuid, drive, device, partmap, abstraction”. On peut également indiquer à “grub-probe” un fichier “device.map” spécifique (par défaut c'est /boot/grub/device.map), ou un chemin vers les fichiers de configuration à la place d'utiliser l'option “-d” (--device) et un chemin vers un volume:

# grub-probe /boot/grub/ -tabstraction

Pour une liste complète des modules disponibles, vous pouvez jeter un œil dans /boot/grub, ou utiliser:

$ ls -l /boot/grub/ | grep .mod | less
  • GRUB_CMDLINE_LINUX= Cette variable est comparable à la ligne “kopts” de grub “legacy”, on y indique les options permanentes à transmettre au noyau au moment de son chargement. C'est ici qu'on indique les options liées à l'acpi, la verbosité du démarrage… Les options doivent être séparées par un espace, et l'ensemble de la liste encadrée par des guillemets. Cette variable concerne toutes les entrées du menu, y compris “recovery”.
  • GRUB_CMDLINE_LINUX_DEFAULT= Cette variable permet de spécifier les options supplémentaires à passer au noyau (“quiet”, “vga=”, etc… elle ne concerne QUE les entrées par défaut, pas les entrées “recovery”.
  • GRUB_GFXMODE= Permet de choisir la résolution du terminal graphique gfxgrub lorsqu'il est utilisé. Pour connaître les modes supportés par votre carte vidéo, vous pouvez utiliser:
# hwinfo --framebuffer

Le programme “hwinfo” est nécessaire, à installer avec votre gestionnaire de paquets s'il n'est pas déjà présent.
Pour être certain que la résolution sera disponible on peut passer dans un shell grub lors du démarrage (passer en mode édition avec la touche [e], puis [ctrl][c] pour passer sur le shell grub, [esc] pour en sortir). Dans le shell grub on tape :

# vbeinfo

pour connaître la liste des résolutions effectivement disponibles.
Si le matériel le supporte on pourra par exemple utiliser une résolution de 1280×1024 avec des couleurs codés sur 24bit: “GRUB_GFXMODE=1280x1024x24” , ce qui se traduira dans votre grub.cfg par la mention: “set gfxmode=1280x1024x24”. La première valeur donnée est celle par défaut, les suivantes (facultatives) seront utilisées en secours si la première échoue :

GRUB_GFXMODE="1440x900 800x600 640x480"

Attention, si vous utilisez une résolution élevée, supportée par votre matériel, et une image de résolution inférieure, celle-ci ne sera pas affichée, ou ne couvrira qu'une partie de l'écran. Il faut donc créer une image à la bonne résolution et en indiquer le chemin dans “/etc/grub.d/05_debian_theme” (voir plus bas).

  • GRUB_GFXPAYLOAD_LINUX=“keep” Cette option est l'équivalent de l'ancienne option noyau “vga=” pour déterminer la résolution des consoles virtuelles lorsqu'on utilise un affichage de type “framebuffer”. La valeur “keep” indique que l'on souhaite conserver la résolution de “GRUB_GFXMODE=”, mais on peut également indiquer une résolution sous la forme “1280×800”. Cette option se traduira dans le fichier grub.cfg (voir ci-dessous) par la mention “set gfxpayload=”.
  • GRUB_BACKGROUND= permet de spécifier le chemin vers une image de fond pour grub, au format jpg, png ou tga. Pour un meilleur rendu utilisez une image à la même résolution que le menu.
  • GRUB_DISABLE_LINUX_UUID=true Permet d'empêcher l'utilisation automatique des UUID pour l'adressage de la partition racine dans le grub.cfg.

Les autres fichiers de configuration se trouvent dans le répertoire /ETC/GRUB.D/, on y trouve sur Debian:

00_header
05_debian_theme
10_hurd
10_linux
20_memtest86+
30_os-prober
40_custom

On remarque le préfixe numérique, à la manière des scripts des niveaux d'exécutions “rc.*”. Ce préfixe détermine l'ordre dans lequel les scripts seront lus par “grub-mkconfig”.

00_header gère la plupart des variables contenues dans /etc/default/grub, il n'y a normalement aucune raison de modifier ce script. On y trouve des fonction d'évaluation des variables contenu dans le /etc/default/grub, afin de les passer au grub.cfg, en voici un exemple:

[...]
for i in ${GRUB_PRELOAD_MODULES} ; do
  echo "insmod $i"
done

if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi
if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=4 ; fi
if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi

cat << EOF
set default=${GRUB_DEFAULT}
set timeout=${GRUB_TIMEOUT}
EOF
[...]

Ce fragment de fichier montre que le script “00_header” sources les valeurs des variables relatives au chargement de modules spécifiques, du choix par défaut dans le menu, du temps avant démarrage automatique du choix par défaut, et de la résolution attribuée à gfxgrub.

05_debian_theme sera spécifique à votre distribution, il gère les éléments du thème graphique utilisé, comme l'image de fond du menu grub2 et les couleurs des polices. Pour spécifier un chemin vers une image particulière on pourra modifier la partie concernant le thème par défaut:

[...]
# check for usable backgrounds
use_bg=false
if [ "$GRUB_TERMINAL_OUTPUT" = "gfxterm" ] ; then
  for i in {/boot/grub,/usr/share/images/desktop-base}/moreblue-orbit-grub.{png,tga} ; do
[...]

pour inclure le chemin vers une image différente (ici les images inclues dans le paquets “grub2-splashimages”):

[...]
# check for usable backgrounds
use_bg=false
if [ "$GRUB_TERMINAL_OUTPUT" = "gfxterm" ] ; then
  for i in {/boot/grub,/usr/share/images/desktop-base,/usr/share/images/grub}/Windbuchencom.{png,tga} ; do
[...]

Pour modifier la couleur de la police:

[...]
# set the background if possible
if ${use_bg} ; then
  prepare_grub_to_access_device `${grub_probe} --target=device ${bg}`
  cat << EOF
insmod ${reader}
if background_image `make_system_path_relative_to_its_root ${bg}` ; then
  set color_normal=black/black
  set color_highlight=magenta/black
else
EOF
fi
[...]

Ne modifiez pas ce qui concerne le thème par défaut, il constitue le choix de secours si votre personnalisation ne fonctionne pas.

10_hurd, 10_linux sont des scripts spécifiques au chargement d'un type de noyau, respectivement pour les systèmes GNU-HURD ou GNU-Linux. (Voir ici pour HURD ). Ces scripts génèrent les entrées pour le système par défaut du grub.cfg, il n'y a aucune raison de les modifier directement, ces scripts sources les informations de /etc/default/grub, et évaluent un grand nombre de paramètres comme la présence d'un initrd, l'emplacement, l'UUID et le type de volume sur lequel est situé la racine du système (“/”)… etc.

20_memtest86+ Intègre une entrée pour lancer l'application de test de mémoire “memtest” si installée.

30_os-prober est issue du paquet “os-prober”, c'est un script additionnel à grub2 qui détecte les autres systèmes d'exploitation installés, et ajoute une entrée dans le grub.cfg automatiquement.

40_custom C'est le script qui pourra faire l'objet de vos modifications, on peut y intégrer un script spéfique, une entrée supplémentaire pour un système qui ne serait pas détecté par “os-prober”, …etc. Par défaut il ne contient rien, ici un exemple avec une entrée ajoutée pour un système Ubuntu:

#!/bin/sh
exec tail -n +3 $0
# This file is an example on how to add custom entries
#
#Ubuntu Jaunty sur /dev/sdc1
menuentry "Ubuntu (on /dev/sdc1)" {
        set root=(hd2,1)
        linux   /vmlinuz root=/dev/sdc1 ro quiet silent
        initrd  /initrd.img
}

On reviendra sur la syntaxe des entrées du grub.cfg dans le chapitre suivant.

On peut également créer son propre script, et lui attribuer un préfixe libre afin de déterminer l'ordre de son exécution. Par exemple pour ajouter la même entrée pour Ubuntu, après les entrées par défaut mais avant les systèmes détectés par “40_os-prober” et l'entrée de “memtest”, on pourra créer “11_ubuntu-jaunty”.
Veillez à ce que le script soit exécutable.

Le fichier grub.cfg

Le remplaçant du fichier /boot/grub/menu.lst de grub “legacy” est /boot/grub/grub.cfg. Le grub.cfg ne doit pas être édité à la main, tout changement y sera rapidement écrasé. Pour changer temporairement une entrée du grub.cfg on utilisera plutôt le shell de grub2 lors du démarrage, pour un changement permanent on créera un script dans /etc/grub.d.

Un exemple de fichier grub.cfg:

#
# NE PAS ÉDITER CE FICHIER
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
  load_env
fi
set default="0"
if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  insmod vbe
  insmod vga
  insmod video_bochs
  insmod video_cirrus
}

insmod raid
insmod mdraid
insmod part_msdos
insmod ext2
set root='(md/0)'
search --no-floppy --fs-uuid --set 116eb616-a149-4427-800a-12992a1f9492
if loadfont /usr/share/grub/unicode.pf2 ; then
  set gfxmode=1920x1080 1440x900 1280x720
  load_video
  insmod gfxterm
fi
terminal_output gfxterm
insmod raid
insmod mdraid
insmod part_msdos
insmod ext2
set root='(md/0)'
search --no-floppy --fs-uuid --set 116eb616-a149-4427-800a-12992a1f9492
insmod tga
background_image -m stretch /usr/share/images/grub/vladstudio_leaf.tga
insmod raid
insmod mdraid
insmod part_msdos
insmod ext2
set root='(md/0)'
search --no-floppy --fs-uuid --set 116eb616-a149-4427-800a-12992a1f9492
set locale_dir=($root)/boot/grub/locale
set lang=fr
insmod gettext
set timeout=3
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/05_debian_theme ###
insmod raid
insmod mdraid
insmod part_msdos
insmod ext2
set root='(md/0)'
search --no-floppy --fs-uuid --set 116eb616-a149-4427-800a-12992a1f9492
insmod tga
if background_image /usr/share/images/grub/vladstudio_leaf.tga; then
  true
else
  set menu_color_normal=cyan/blue
  set menu_color_highlight=white/blue
fi
### END /etc/grub.d/05_debian_theme ###

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Debian GNU/Linux, avec Linux 2.6.37.2-deb64' --class debian --class gnu-linux --class gnu --class os {
	set gfxpayload=1920x1080 1440x900 1280x720
	insmod raid
	insmod mdraid
	insmod part_msdos
	insmod ext2
	set root='(md/0)'
	search --no-floppy --fs-uuid --set 116eb616-a149-4427-800a-12992a1f9492
	echo	'Chargement de Linux 2.6.37.2-deb64 ...'
	linux	/boot/vmlinuz-2.6.37.2-deb64 root=UUID=116eb616-a149-4427-800a-12992a1f9492 ro  
	echo	'Chargement du disque mémoire initial ...'
	initrd	/boot/initrd.img-2.6.37.2-deb64
}
menuentry 'Debian GNU/Linux, avec Linux 2.6.37-2-amd64' --class debian --class gnu-linux --class gnu --class os {
	set gfxpayload=1920x1080 1440x900 1280x720
	insmod raid
	insmod mdraid
	insmod ext2
	set root='(md/0)'
	search --no-floppy --fs-uuid --set 116eb616-a149-4427-800a-12992a1f9492
	echo	'Chargement de Linux 2.6.37-2-amd64 ...'
	linux	/boot/vmlinuz-2.6.37-2-amd64 root=UUID=116eb616-a149-4427-800a-12992a1f9492 ro  
	echo	'Chargement du disque mémoire initial ...'
	initrd	/boot/initrd.img-2.6.37-2-amd64
}
### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/40_custom ###
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###

Vous pouvez voir que le fichier est divisé en fonction des fichiers de configuration que nous venons de détailler. Il s'agit ici de démarrer un système Debian sur volumes raid, d'utiliser gfxterm avec une image de fond pour le menu. Les scripts “10_hurd”, “30_os-prober”, ou “40_custom” auraient pu être retiré de /etc/grub.d pour alléger l'aspect du fichier grub.cfg, ils ont été laissé pour montrer le résultat de leur prise en compte ordonnée.

Installer grub2 sur un disque

Installer grub2 pour démarrer un système, en dehors de l'installation du programme lui-même avec le gestionnaire de paquets, s'effectue à l'aide de commandes spécifiques:

  • grub-install
# grub-install --recheck "(hd0)"

“hd0” désigne le premier disque, l'option “--recheck” est facultative, elle va vérifier la liste des périphériques même si un fichier /boot/grub/device.map, et affichera la table sur la console. C'est la seule commande indispensable à connaître pour installer grub2 sur le secteur d'amorçage d'un disque.
Si votre système comporte un lecteur de disquette, et que celui-ci est listé dans le fichier /boot/grub/device.map, il vaut mieux ajouter l'option “--no-floppy” à la commande d'installation pour éviter que le lecteur de disquette ne se retrouve positionné comme cible pour “/”.
On peut utiliser la notation “/dev/sda” (par exemple) au lieu de “(hd0)” si désiré.

  • grub-mkconfig (update-grub)

Pour des raisons de compatibilité la commande “update-grub” fonctionne toujours avec grub2, mais avec les versions récentes c'est “grub-mkconfig” qu'il faut utiliser. Cette commande va sourcer tous les scripts dans /etc/grub.d, eux même renvoyant les variables de /etc/default/grub, et générer ou mettre à jour le fichier grub.cfg. Il faut exécuter cette commande après chaque modification d'un script ou d'une variable de configuration de grub2. “grub-mkconfig” est également invoqué automatiquement à l'installation d'un nouveau noyau. La syntaxe est la suivante:

# grub-mkconfig -o /boot/grub/grub.cfg

Sans l'option “-o” (--output) le résultat est écrit sur “stdout” (la console) uniquement, avec l'option le résultat est écrit dans le fichier grub.cfg.

C'est la commande dont l'utilisation est la plus courante.

  • grub-setup

Sert à créer une image de démarrage qui se lancera depuis la partition indiquée (de la forme “(hd0,1)”. Parmi les options, on peut indiquer une partition root (--root-device= ), un autre répertoire que /boot/grub pour implanter l'image (--directory= ), ou encore fournir un fichier device.map différent de celui du système (--device-map= ) (par exemple pour démarrer depuis un système sur clé usb). Cette commande ne s'utilise pas en usage normal.

  • grub-mkdevicemap

Comme sont nom le laisse supposer, cette commande crée un fichier /boot/grub/device.map. À utiliser après un ajout/retrait de disque, une modification dans l'agencement des disques dans le bios…

  • grub-mkrescue

Sert à créer un disque de démarrage, qui peut servir de disque de secours. Par défaut c'est un cdrom qui est créé, mais on peut également créé une disquette avec l'option “--image-type=floppy”. On peut également indiquer des modules à charger avec “--modules=”, et préciser le type d'émulation "el torito" afin de l'adapter au media (cdrom par défaut, ou floppy). Exemple d'utilisation:

# grub-mkrescue --image-type=floppy --emulation=floppy --modules=lvm test.img

L'image résultante peut être gravée (pour une image cdrom) ou on peut utiliser la commande “dd” pour la copier sur une disquette.

  • grub-probe

Permet de s'assurer que l'auto-détection de grub2 fonctionne bien, et de savoir quels modules seront nécessaires à grub2. On indique la cible du test avec l'option “-d” (device), ou avec un chemin vers des fichiers de configuration (/boot/grub). Les paramètres possibles à tester (“--target” ou “-t”) sont “fs, fs_uuid, drive, device, partmap, abstraction”. Exemples d'utilisation:

# grub-probe -d /dev/sda1 --target=fs_uuid
# grub-probe -d /dev/md0 -tabstraction
# grub-probe /boot/grub/ -tabstraction

Son utilisation directe est peu courante en pratique, il est invoqué par “grub-install” ou “grub-mkconfig”.

Modification d'une entrée de menu lors du démarrage

Lors du démarrage, vous pouvez sélectionner une entrée du menu, et entrer en mode d'édition en tapant [e]. L'édition se fait classiquement, naviguez avec les flèches du clavier, attention au clavier qui se trouve alors en QWERTY ! Pour démarrer avec l'entrée modifiée utilisez les touches [ctrl][x] . La modification est temporaire, elle n'est pas écrite dans le grub.cfg.
À partir du mode d'édition vous pouvez ouvrir une console (un “shell”) grub avec la combinaison de touches [ctrl][c], on revient au mode édition avec [esc], voir plus bas le chapitre “récupération” pour plus de détails sur le mode “shell” interactif de grub.

Démarrer windows

Cette partie est à prendre avec prudence, l'auteur n'utilise pas de systèmes d'exploitation Microsoft. Les procédures décrites ont été brièvement testées avec une image d'installation de Windows XP. Rien ne garantie que cela fonctionne avec Windows Vista. (De toute façon, il vaut mieux que ça ne démarre pas dans ce cas là… ;-) )

Pour démarrer windows vous utiliserez le “chainload”, c'est à dire le chaînage de plusieurs gestionnaires de démarrage. Pour un cas classique avec Windows (partition ntfs) sur la première partition du premier disque dur, on créera un fichier personnalisé dans /etc/grub.d (exemple:12_windows) ou on ajoutera à “40_custom” le contenu suivant :

#!/bin/sh
exec tail -n +3 $0

#Windows sur /dev/sda1

insmod ntfs
insmod chain
menuentry "Microsoft Windows XP" {
        set root=(hd0,1)
        chainloader (hd0,1)+1
	boot
}

On trouve plusieurs syntaxes pour l'option “chainloader”, celle indiquée ici est la notation du wiki officiel grub2, mais l'ancienne notation “chainloader +1” semble fonctionner également.

L'option de “grub-legacy” “makeactive” n'est normalement plus nécessaire. L'option “map”, destinée à inverser la hiérarchie des disques afin de “faire croire” à Windows qu'il réside sur le premier disque, se nomme maintenant “drivemap” avec grub2.

La plupart du temps l'installation du paquet “os-prober” suffira à détecter le système et ajouter une entrée dans le grub.cfg .

Voici un exemple d'entrée fonctionnelle et testée pour démarrer Windows7 sur la première partition du disque dur d'un ordinateur portable (UUID de la partition Windows7 “6a60fd8160fd53f3”) , depuis grub2 installé par Ubuntu (“dual boot”, Ubuntu est sur la seconde partition du disque dur) :

menuentry "Windows 7 (loader) (on /dev/sda1)" {
	insmod ntfs
	set root=(hd0,1)
	search --no-floppy --fs-uuid --set 6a60fd8160fd53f3
	chainloader +1
}

Récupération en cas de problème

Si une de vos manipulation vous laisse devant un écran désespérément vide au prochain démarrage, il reste en général un bon espoir de récupérer l'installation.

Depuis le shell grub

Pas de panique !

Vous voila au pied du mur (ou du shell plus exactement), c'est le pire des cas où grub n'arrive pas à lancer l'initrd (l'initial ram disk) ou le noyau. Vous arrivez sur une console de récupération avec pour prompt “grub rescue”. La première commande à essayer est help, ça ne fait pas vraiment viril mais ça renseigne sur les commandes disponibles dans cet environnement de récupération.

La commande, set sans argument affiche les valeurs des variables actuellement définies. Ici on voit que la partition cible pour la configuration de grub (“prefix=”) est (hd0,msdos1)/grub, la partition “root” est celle où se trouvent l'initrd et le noyau à charger. Ici il s'agit d'une partition /boot séparée qui est réellement située en hd0,msdos3.

On utilise ensuite ls pour lister les disques et partitions reconnus par grub2.

Nous allons remettre de l'ordre en définissant les variables à leurs valeurs correctes.

On réutilise la commande set mais cette fois en lui passant en argument une variable et sa valeur. Remarquez l'adressage du répertoire qui supporte la configuration de grub (“prefix”) (hd0,msdos3)/grub. “msdos” signifie que nous avons affaire à une table de partition de type “classique” dos. Ici /boot est sur une partition séparée, sur un système sans partition /boot séparée la valeur aurait pu être prefix=(hd0,msdos3)/boot/grub.
On fixe de la même façon la valeur de la partition “root” qui contient l'initrd et le noyau. Notez que les parenthèses ne sont pas indispensables ici car il n'y a rien qui suive hd0,msdos2.

Une fois ces valeurs fixées, la variable “prefix” est utilisée comme racine des commandes suivantes, il n'est pas nécessaire de l'écrire à chaque nouvelle commande. Ici on utilise “insmod” pour charger le module “normal” permettant de basculer grub du mode de récupération au mode normal, et d'accéder au menu grub.

Vous pouvez voir la liste des modules déjà chargé avec lsmod.
Vous pouvez également voir les modules disponibles en listant le contenu du répertoire /boot/grub avec ls /boot/grub. On active donc le mode normal avec la commande normal (original, non?).

En mode normal l'éventail de commandes disponibles est bien plus vaste, utilisez [tab] pour les lister, et la console supporte l'auto-complétion comme un shell bash classique.
Ça va mieux, on arrive sur le menu, on peut alors si besoin vérifier les entrées en passant en mode d'édition avec la touche [e].

Lorsque tout est en ordre on utilise les touches [ctrl] et [x] pour démarrer l'entrée sélectionnée. Si on veut quitter le mode d'édition c'est [esc], toutes les modifications seront alors perdues. Pour lister les choix possibles à n'importe quel moment utilisez la touche [tab] (tabulation).

Une astuce si vous pensez que l'UUID de la partition système est erronée vous pouvez supprimer totalement la ligne :

search --no-floppy --fs-uuid --set 

Ensuite remplacer l'adressage de la partition root par UUID avec sa valeur “classique” :

root=UUID=
devient
root=/dev/sdx,y



Victoire ! Ça démarre. Prenez soin ensuite de mettre en ordre votre configuration, car aucun des changements effectués en mode de récupération n'est permanent, au prochain démarrage vous êtes bon pour recommencer !

Résumé des commandes utilisées

  • help Affiche l'aide
  • ls Liste les volumes et partitions reconnus, ou leur contenu
  • set Liste les variables et leurs valeurs
  • set prefix= Fixe l'emplacement du répertoire de configuration, de la forme (hd0,1)/boot/grub
  • set root= Fixe la partition racine
  • lsmod Liste les modules déjà chargés
  • insmod Charge les modules nécessaires (linux,boot,raid,lvm,crypt,normal…)
  • normal Fait basculer en mode normal (menu)

Cet exemple est tiré d'un système Linux Mint dont la partition /boot a été déplacée avec GParted.

Utiliser un "chroot"

Si vous n'atteignez même pas le shell de secours de grub2, il vous reste la solution du “chroot”. Cela consiste à obtenir un shell sur le système cible (celui que vous n'arrivez plus à démarrer) depuis un autre système (live-cd par exemple). Le “chroot” va vous permettre de réinstaller grub2, modifier sa configuration, etc… comme si vous agissiez depuis le système cible.

Vous devez donc démarrer sur un live-cd (ou utiliser un autre système installé si vous êtes en multi-boot), et créer un répertoire qui va accueillir le système cible :

# mkdir /mnt/cible

Ensuite vous allez monter le système cible sur ce répertoire, ne vous trompez pas lors du montage ! Pour avoir une bonne “vision” de la numérotation de vos partitions vous pouvez utiliser (au choix) :

# fdisk -l
# parted -l

ou encore lancer un éditeur de partition comme Gparted. Une fois identifiée la partition racine du système cible (ici on utilisera “/dev/sda2”), montez là :

# mount /dev/sda2 /mnt/cible

:!: Si vous avez une partition /boot séparée (ici on imagine qu'il s'agit de “/dev/sda1”), vous devez la monter absolument à cette étape :

# mount /dev/sda1 /mnt/cible/boot

Évidemment si vous n'avez pas de partition /boot séparée, sautez cette étape.
Si la partition “/boot” est déjà montée sur le système cours d'utilisation (cas du multiboot), vous pouvez soit la démonter avant de la remonter sur le système cible, soit utiliser l'option “--bind” de la commande “mount” (voir ci-dessous).

Enfin vous devez rendre accessible au système cible l'ensemble des périphériques, ce qui est fait en montant le répertoire “/dev” du système en utilisation (le live-cd par exemple). Comme “/dev” est normalement déjà monté une première fois sur le système en cours d'utilisation, on utilise l'option “--bind” de la commande “mount” qui permet de remonter sur un second point de montage un système de fichier déjà monté :

# mount --bind /dev /mnt/cible/dev

On peut également utiliser la notation “mount -o bind”, le “-o” indiquant une option.

Idem pour /proc et /sys :

# mount --bind /proc /mnt/cible/proc
# mount --bind /sys /mnt/cible/sys

Voila, il ne vous reste plus qu'à exécuter le “chroot” proprement dit :

# cd /mnt/cible/
# chroot . ./bin/bash

À partir de maintenant les commandes exécutées dans la console agissent sur le système cible, et non plus sur le système en cours d'utilisation (live-cd etc…). On peut donc réinstaller grub2 sans problème (ici on imagine qu'il doit être réinstaller sur le secteur d'amorçage (“MBR”) du premier disque) :

# grub-install "(hd0)"

N'oubliez pas de mettre à jour le grub.cfg par la suite avec, au choix :

# update-grub2
# grub-mkconfig -o /boot/grub/grub.cfg

Vous pouvez également éditer la configuration de grub2, par exemple si vous devez éditer le fichier /etc/default/grub il vous suffit de taper :

# nano /etc/default/grub

Pour quitter le “chroot”, tapez simplement “exit” dans la console, ou utilisez la combinaison de touche [ctrl][c].

Si par (excès de) sécurité vous voulez démonter les partitions du système cible avant de redémarrer, utilisez simplement “umount” :

# umount /mnt/cible/dev
# unmount /mnt/cible/boot
# unmount /mnt/cible/sys
# unmount /mnt/cible/proc
# umount /mnt/cible

C'est fini, il ne vous reste qu'à redémarrer pour tester vos modifications, et croiser les doigts… ;-)

grub2 et systèmes de fichiers "exotiques"

Le système de fichier ext4, “remplaçant” de ext3, est maintenant le choix par défaut pour de nombreuses distributions, il est nativement supporté par grub2. En revanche s'il vous prend l'idée d'essayer btrfs, xfs, un système de fichiers chiffré ou d'autres systèmes de fichier “exotiques” vous devrez vous assurer que votre version de grub le supporte. Pour ne pas avoir de mauvaise surprise utilisez une partition /boot formatée en ext3/4 séparée.

À partir de grub-1.99 le système de fichier btrfs est supporté, le support du raid logiciel (mdadm) a été consolidé avec la possibilité de démarrer directement sur un raid partitionnable (métadonnées de type 1.*).

Utilitaires de récupération

Super Grub Disk (alias “SGD”) supporte grub2 dans ses version 1.* et avec le CDRom de sauvetage “Rescatux”. Le polyvalent System Rescue CD intègre Super Grub Disk (“rescue floppy”) parmi les options de démarrage (tapez grubdisk à l'invite de démarrage).
Ubuntu “Karmic Koala” et suivant utilisent par défaut grub2, un live-cd de ces distributions pourra donc être un bon outils de récupération.

Compiler grub2 depuis les sources

Si vous rencontrez des bugs bloquant avec la version de grub fournie par votre distribution, pour compléter un rapport de bug en vérifiant si le dernier code disponible corrige un problème, ou par curiosité, il y a quelques bonnes raisons de vouloir compiler grub depuis les sources de développement.

Récupérer les sources

Le code est disponible via un système de gestion de version “Bazaar” (bzr). Vous avez donc besoin de la commande “bzr”.

$ bzr branch http://bzr.savannah.gnu.org/r/grub/trunk/grub

Cette commande créera dans le répertoire courant un répertoire “grub” contenant le code source.

Alternativement, archives disponibles sur le serveur ftp.

Vous pouvez jeter un œil sur le journal des changements (“Changelog”). Un exemple avec l'ajout d'un patch pour identifier les volumes raid par leur UUID.

2011-04-17  Vladimir Serbinenko  <phcoder@gmail.com>

	Identify RAID by its UUID rather than (guessed) name.

	* grub-core/disk/raid.c (ascii2hex): New function.
	(grub_raid_open): Accept mduuid/%s specification.
	* grub-core/kern/emu/getroot.c (get_mdadm_name): Revamped into ...
	(get_mdadm_uuid): ... this.
	(grub_util_get_grub_dev): Use mduuid/%s if UUID is available.

Recherche avec grep des nouveautés concernant le support du système de fichier btrfs.

$ grep -ni btrfs ~/grub/ChangeLog

213:    * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Silence spurious
611:    * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge
659:    btrfs subvolume.
681:    * NEWS: Drop obsolete entry about probe-only btrfs support.
689:    * NEWS: Add btrfs support.
694:    BtrFS support. Written by me (Vladimir) with important bugfixes and
698:    * grub-core/Makefile.core.def (btrfs): Add crc.c.
699:    * grub-core/fs/btrfs.c: Stub replaced with real implementation.
732:    * grub-core/fs/btrfs.c (grub_btrfs_fs) [GRUB_UTIL]: Set
733:    reserved_first_sector to 1.  btrfs reserves plenty of space for boot
1792:   * grub-core/fs/btrfs.c (grub_btrfs_mount): Transform out of range into
2427:   * grub-core/fs/btrfs.c (grub_btrfs_mount): Replace grub_strncmp()
4555:   Basic Btrfs support (detection and UUID).
4557:   * grub-core/fs/btrfs.c: New file.
4558:   * Makefile.util.def (library): Register btrfs.c.
8539:   Add btrfs probing support, currently only in the single-device case.

Dépendances

Liste des dépendances, les noms des paquets sont ceux de Debian :

  • bzr (pour récupérer le dernier code disponible)
  • autogen
  • autoconf
  • bison
  • flex
  • libdevmapper-dev
  • libfreetype6-dev

configuration et installation

$ ./configure --prefix=/usr/local --disable-grub-emu-usb --disable-grub-emu-sdl --disable-efiemu --disable-mm-debug

[...]
*******************************************************
GRUB2 will be compiled with following components:
Platform: i386-pc
With devmapper support: Yes
With memory debugging: No
efiemu runtime: No (explicitly disabled)
grub-mkfont: Yes
*******************************************************

Les options indiquées ici le sont à titre d'exemple, elles sont facultatives. Un simple “./configure” peut être suffisant. Quelques options supplémentaires que l'on peut (des)activer lors de la configuration.

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --disable-dependency-tracking  speeds up one-time build
  --enable-dependency-tracking   do not reject slow dependency extractors
  --disable-nls           do not use Native Language Support
  --disable-rpath         do not hardcode runtime library paths
  --disable-largefile     omit support for large files
  --disable-werror        do not use -Werror when building GRUB
  --enable-efiemu         build and install the efiemu runtimes
                          (default=guessed)
  --enable-mm-debug       include memory manager debugging
  --enable-grub-emu-usb   build and install the `grub-emu' debugging utility
                          with USB support (default=guessed)
  --enable-grub-emu-sdl   build and install the `grub-emu' debugging utility
                          with SDL support (default=guessed)
  --enable-grub-emu-pci   build and install the `grub-emu' debugging utility
                          with PCI support (potentially dangerous)
                          (default=no)
  --enable-grub-mkfont    build and install the `grub-mkfont' utility
                          (default=guessed)
  --enable-device-mapper  enable Linux device-mapper support (default=guessed)
$ make

À ce stade vous devez désinstaller la version de grub qui est actuellement présente sur votre système, avant de procéder à l'installation. C'est le point de non retour ;-)

# make install

Une fois l'installation achevée n'oubliez pas de mettre à jour votre configuration, recréez une fichier “device.map” (grub-mkdevicemap) pour vérifier que grub détecte bien vos partitions, réinstallez le code dans le secteur de démarrage du disque (grub-install) et recréez votre fichier grub.cfg (grub-mkconfig).

Pour désinstaller grub utilisez :

# make uninstall

Et n'oubliez pas de conserver une version en état de marche installée ;-).

Le programme compagnon “os-prober” qui sert à détecter les autres systèmes d'exploitation présents sur la machine n'est pas fourni par grub. Vous pouvez utiliser la version de votre distribution, si vous le désinstallez en même temps que grub celui-ci fonctionnera normalement mais les autres systèmes ne seront plus détecté automatiquement.

Bon amusement.

Liens

expert/grub2.txt · Dernière modification: 2015/02/26 21:18 par ideefixe