dimanche 28 octobre 2012

Clef de secours (seconde partie)

Suivant les indications figurant dans le billet Clef de secours, nous avons rendu une clef usb bootable en installant dans son secteur d'amorce un chargeur grub qui pointe vers un dossier grub situé sur cette même clef.
Dans ce dossier se trouve un fichier de configuration grub.cfg contenant par exemple:
search --no-floppy --label --set=root Ubuntu 
chainloader +1 
boot
Si tout fonctionne bien, booter via la clef est transparent et le menu qui surgit est celui du fichier de configuration utilisé par le chargeur grub dont la partie initiale se trouve sur le VBR (Volume Boot Record) de la première partition trouvée dont le label est "Ubuntu".
Dans le cas contraire, si cela se passe mal, il existe diverses possibilités. L'une d'elles consiste à ce que l'on atterrisse directement dans un shell grub.
Nous sommes alors à la tête d'un mini-système d'exploitation et nous pouvons lancer au niveau de ce shell grub un certain nombre de commandes, dont la commande set qui renvoie la liste de différentes variables d'environnement avec leur valeur.
Examinant l'output de cette commande nous y trouvons quelque chose comme:
prefix=(hd0,msdos1)/grub
root=hd1,msdos3
Cela montre que l'exécution de la commande search a été couronnée de succès car au démarrage la valeur de la variable root est fixée à partir de celle de la valeur prefix.
En fait la variable prefix indique à grub où se trouvent les modules et les fichiers images (*.img) dont il a besoin pour fonctionner: dans le dossier grub de la partition 1 de la clef usb (qui est considérée comme hd0 puisqu'on a booté dessus).
Puisque search a bien fonctionné, la raison de l'échec du lancement du système linux est a chercher ailleurs: le VBR désigné par la commande chainloader ne contient pas de grub, ou celui-ci est inopérant.
Sans doute grub n'a-t-il jamais été installé sur ce VBR?

La commande multiboot.
Mais pas de problèmes: il n'est pas nécessaire de procéder à cette installation. Pour charger le grub du système linux que nous souhaitons démarrer, il suffit de saisir dans notre shell grub les commandes:
grub> multiboot /grub/i386-pc/core.img 
grub> boot
Ceci implique bien sûr que le label Ubuntu désigne une partition qui sera montée en /boot.
Si Ubuntu désigne la partition racine et qu'aucune partition n'est montée en /boot les commandes à saisir sont:
grub> multiboot /boot/grub/i386-pc/core.img 
grub> boot
Dans les deux cas, le chemin vers core.img n'est pas nécessairement celui indiqué ici. Mais comme la complétion fonctionne très bien, il est aisé de vérifier si on est sur la bonne voie où pas.
Une autre possibilité si cela se passe mal dès le départ est que l'on soit finalement renvoyé vers le chargeur principal. Mais normalement si nous utilisons la clef de secours c'est justement parce que le chargeur principal ne nous permet plus d'amorcer notre système linux. Le désastre étant provoqué par la commande boot figurant dans le grub.cfg de la clef, nous la supprimons avant une nouvelle tentative. Nous atterrissons cette fois dans un shell grub.
L'output de la commande set donne:
prefix=(hd0,msdos1)/grub 
root=hd0,msdos0
La variable root est restée inchangée! La commande search n'a rien donné: aucune partition trouvée avec le label indiqué (Ubuntu dans notre exemple). Il importe avant de poursuivre de donner à la variable root la valeur qui convient, soit directement, par exemple:
grub> set root=(hd1,3)
soit en lançant une nouvelle commande search adaptée.
Évidemment pour savoir quelle est la valeur à attribuer à root, il faut avoir un minimum de connaissance sur la structure du système linux que l'on veut amorcer: quelles sont les partitions utilisées?
Si nous fixons nous-même directement la valeur de root, il peut être utile de vérifier que nous sommes au bon endroit  à l'aide de la commande
grub> ls /
Ici nous vérifions que nous sommes bien sur la partition /boot d'un système Fedora 17 avant de saisir les commandes permettant de charger le grub de ce système:


Si la commande ls / retourne des choses du genre etc/ boot/ home/ ..., cela signifie que nous sommes sur la partition racine d'un système.
Il convient alors d'exécuter la commande ls /boot. Si cette dernière commande ne retourne rien, cela signifie que notre système fonctionne avec en plus de la partition racine, une partition à monter en /boot.

Notons que l'emploi de la commande multiboot n'est pas réservé à une utilisation dans un shell grub: elle peut aussi être utilisée dans un fichier grub.cfg.

La commande configfile.
Une alternative à la commande multiboot est l'utilisation de la commande configfile:
grub> configfile /grub/grub.cfg
Cette commande provoque l'affichage du même menu que celui obtenu avec la commande multiboot. La différence est que cette fois le grub du système linux (dont les fichiers img et mod se trouvent sur le disque dur) n'est pas chargé. On reste dans le même grub (celui de la clef), mais on lui demande d'utiliser le fichier de configuration dont le nom absolu est (hd1,3)/boot/grub (si la variable root vaut hd1,3)

Amorçage en ligne de commande.
Supposons maintenant que notre système linux ne comprenne aucun chargeur où que celui-ci est inopérant.
Impossible d'utiliser la commande multiboot (ou configfile).
Mais rien n'est perdu.
Quelques commandes tapées dans notre shell grub (où placées dans le grub.cfg) suffisent à amorcer le système:

grub> set root=(hd1,3) 
grub> linux /vmlinuz-3.5.0-17-generic root=LABEL=u-root ro
grub> initrd /initrd-3.5.0-generic 
grub> boot

Il est important de ne pas confondre la variable root de la ligne 1 qui se rapporte à la partition où se trouve le noyau (ici vmlinuz-3.5.0-17-generic) avec l'option root de la commande linux qui indique au noyau quelle est la partition racine.
Notons que grâce à la complétion il n'est pas nécessaire de connaître de connaître le nom exact des fichiers vmlinuz et initrd.
Il est cependant utile de connaître le label de la partition racine.
Rappelons que la commande blkid exécutée en root (par exemple depuis un live CD)  fournit tous les renseignements nécessaires.
Signalons enfin que si aucune partition n'est à monter dans /boot, la variable root désigne alors la partition racine puisque c'est elle qui contient le noyau. Mais malgré tout il faut encore indiquer au noyau quelle est la partition racine.
Dans ce cas les commandes à saisir seraient par exemple:

grub> set root=(hd1,3)
grub> linux /boot/vmlinuz-3.5.0-17-generic root=LABEL=Ubuntu ro
grub> initrd /boot/initrd-3.5.0-generic
grub> boot