Gérer les entrées de grub /Grub et mac

A terme l’idée est de le faire sur un macbook pro.

Mais afin de roder la manip et sans qu’il n’y ai aucune conséquence si je détruis un système, j’ai monté un macbook “normal” (ni pro, ni air), avec très exactement la même configuration, obtenu de la même façon, à savoir plus précisement :

-sda1 : Efi boot
-sda2 : Mac OS V1
-sda3 : Recovery V1
-sda4 : MacOS V2
-sda5 : recovery V2
-sda6 : Debian Jessie
-sda7 : /home
-sda8 : SWAP
-sda9 : espace libre.

Voici ce que m’affiche exactement grub au démarrage :

  • Debian GNU/Linux
  • Options avancées pour Debian
  • Mac OS X (32 bits) (sur /dev/sda2)
  • Mac OS X (64 bits) (sur /dev/sda2)
  • Mac OS X (32 bits) (sur /dev/sda4)
  • Mac OS X (64 bits) (sur /dev/sda4)
  • MacOS : L’entrée que j’ai rajouté manuellement et qui pointe vers la dernière partition mac utilisée en passant par la pression de “alt” au démarrage.

En réalité, je n’ai pas regardé du côté de os-prober, mais il m’affiche la même chose :
/dev/sda2:Mac OS X:MacOSX:macosx
/dev/sda4:Mac OS X:MacOSX:macosx

L’installation de mon grub s’est faite dans tous les cas avec l’installeur debian. Normalement rien n’est passé à la trappe, j’imagine. Les macOS étaient déjà la avant debian.

Je ne connais pas du tout les Mac mais je connais un peu GRUB et l’amorçage EFI.
Peux-tu confirmer que :

  • le paquet grub-efi-amd64 est installé
  • la partition système EFI /dev/sda1 est montée sur /boot/efi
  • le chargeur GRUB EFI 64 bits est installé dans /boot/efi/EFI/debian/grubx64.efi et /boot/grub/x86_64-efi
  • il n’y a pas de répertoire /boot/grub/i386-pc (GRUB BIOS) ni /boot/grub/i386-efi (GRUB EFI 32 bits)

Ensuite, je serais intéressé par :

  • la sortie de la commande efibootmgr -v (en root) pour lister les entrées d’amorçage EFI
  • le contenu d’une entrée de menu de GRUB créée automatiquement pour Mac OS X dans le fichier /boot/grub/grub.cfg.

Aussi, peux-tu décrire ce qui se passe lorsque tu sélectionnes une entrée de démarrage pour Mac OS X dans le menu de GRUB ?

Alors,

  • grub-efi-amd64 : installé
  • sda1 : toujours monté en /boot/efi
  • /boot/efi/EFI/debian/grubx64.efi : oui
  • /boot/grub/x86_64-efi/ : il y a un fichier grub.efi (sans “x”).
  • Pas de répertoire i386-pc ou i386-efi dans /boot/grub

Ensuite,

  • efibootmgr -v renvoie :

BootCurrent: 0000
BootOrder: 0000,0080
Boot0000* debian HD(1,28,64000,e5db7ba7-4363-49be-9cdd-a3ddc8f1e29b)File(\EFI\debian\grubx64.efi)
Boot0080* Mac OS X ACPI(a0341d0,0)PCI(b,0)SATA(0,0,0)HD(4,5dc5de8,5c2be98,ae1fc7b1-29d0-4553-9c8d-949bbca44fe3)
Boot0081* Mac OS X ACPI(a0341d0,0)PCI(b,0)SATA(0,0,0)HD(2,64028,e8c6e940,17cf479b-665e-4a27-8304-8fd353067b75)
Boot0082* ACPI(a0341d0,0)PCI(b,0)SATA(0,0,0)HD(4,5dc5de8,5c2be98,ae1fc7b1-29d0-4553-9c8d-949bbca44fe3)
BootFFFF* ACPI(a0341d0,0)PCI(b,0)SATA(0,0,0)HD(4,5dc5de8,5c2be98,ae1fc7b1-29d0-4553-9c8d-949bbca44fe3)File(\System\Library\CoreServices\boot.efi)

Le contenu d’une entrée MacOS générée automatiquement dans /boot/grub/grub.cfg

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

menuentry ‘Mac OS X (32 bits) (sur /dev/sda2)’ --class osx --class darwin --class os $menuentry_id_option ‘osprober-xnu-32-6201e6e69aa6d78b’ {
insmod part_gpt
insmod hfsplus
set root='hd0,gpt2’
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 6201e6e69aa6d78b
else
search --no-floppy --fs-uuid --set=root 6201e6e69aa6d78b
fi
load_video
set do_resume=0
if [ /var/vm/sleepimage -nt10 / ]; then
if xnu_resume /var/vm/sleepimage; then
set do_resume=1
fi
fi
if [ $do_resume = 0 ]; then
xnu_uuid 6201e6e69aa6d78b uuid
if [ -f /Extra/DSDT.aml ]; then
acpi -e /Extra/DSDT.aml
fi
if [ /kernelcache -nt /System/Library/Extensions ]; then
xnu_kernel /kernelcache boot-uuid=${uuid} rd=*uuid
else
xnu_kernel /mach_kernel boot-uuid=${uuid} rd=*uuid
if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
xnu_mkext /System/Library/Extensions.mkext
else
xnu_kextdir /System/Library/Extensions
fi
fi
if [ -f /Extra/Extensions.mkext ]; then
xnu_mkext /Extra/Extensions.mkext
fi
if [ -d /Extra/Extensions ]; then
xnu_kextdir /Extra/Extensions
fi
if [ -f /Extra/devprop.bin ]; then
xnu_devprop_load /Extra/devprop.bin
fi
if [ -f /Extra/splash.jpg ]; then
insmod jpeg
xnu_splash /Extra/splash.jpg
fi
if [ -f /Extra/splash.png ]; then
insmod png
xnu_splash /Extra/splash.png
fi
if [ -f /Extra/splash.tga ]; then
insmod tga
xnu_splash /Extra/splash.tga
fi
fi
}

Que se passe-t-il lorsque je lance une entrée Mac OS générée par grub ?
Le fond d’écran demeure, le tableau de choix disparaît automatiquement, en 15 secondes des écritures systèmes arrivent en se mélangeant au fond d’écran. Je n’en tire rien de très concret :

Tout d’abord une phase avec :

error : hibbernate header has incorrect magic number,

puis une seconde phase ou ça plante réellement.

Comme je l’ai écrit je ne connais rien au Mac et ni le contenu de l’entrée de menu dans grub.cfg ni les entrées d’amorçage EFI pour Mac OS X (entrées d’amorçage sans exécutable *.efi) ne me parlent.

La seule chose familière est le chargement de fichiers exécutables *.efi dans l’entrée d’amorçage EFI pour Debian et dans la dernière entrée, de numéro FFFF. Ça ne mènera pas forcément bien loin, je soupçonne que cet exécutable \System\Library\CoreServices\boot.efi sur /dev/sda4 est celui qui est lancé quand GRUB quitte avec la command exit.

Tu pourrais explorer un peu le contenu de la partition système EFI ainsi que les partitions Mac OS à la recherche d’autres fichiers *.efi.

Ok, j’ai compris. Comme tu le fais remarquer, si j’observe le résultat de efibootmgr -v je constate que les seules systèmes accessibles directement par grub sont ceux qui disposent de leurs fichiers *.efi.

Le \System\Library\CoreServices\boot.efi affiché par BootFFFF est celui qui pointe vers sda4 comme tu le dis, soit l’un des deux systèmes mac réelle (pas une partition recovery), il s’agit typiquement d’une architecture mac. L’adresse du fichier boot.efi pour mon premier système mac est donc toute trouvée, c’est exactement la même mais sur sda2 cette fois.

Comment faire pour dire à grub que les fichiers vers lesquels il doit pointer pour chaque entrée se trouve à cette endroit précis ? Autrement dit, comment assigner une adresse de fichier précise à une entrée grub précise ?

Cette manip doit être familière et relativement simple puisqu’elle doit s’effectuer sur linux et surtout, elle est indépendante de l’architecture spécifique mac.

(Sans garantie que ces exécutables EFI permettent d’amorcer Mac OS X)

Il faut utiliser la commande chainloader pour exécuter un programme EFI depuis GRUB. Pour tester, une entrée de menu comme celle-ci devrait faire l’affaire :

menuentry "Mac OS X V2 sur /dev/sda4" {
    insmod part_gpt
    insmod hfsplus
    set root='hd0,gpt4'
    chainloader /System/Library/CoreServices/boot.efi
}

Tu peux aussi tester directement les commandes à l’intérieur du bloc avec le shell de GRUB accessible depuis le menu démarrage de GRUB avec la touche “c” (attention clavier QWERTY) et en terminant avec la commande boot.

Pas vraiment puisqu’habituellement un autre système Linux est amorcé en chargeant directement son noyau et non en exécutant son chargeur EFI (bien que ce soit aussi possible), et tous les chargeurs EFI sont censés être installés dans la partition système EFI qui est prévue à cet effet (c’est pourquoi j’ai suggéré de l’explorer).

Ça fonctionne à merveille. J’ai doublé ton script pour qu’il me permettent d’accéder aussi au macOS sur sda2 et c’est impeccable.

Cependant, je veux clarifier la situation.

Dans /boot/efi/EFI j’ai deux répertoires : “APPLE” et “debian”. Le contenu du répertoire APPLE est très pauvre, il ne contient qu’un seul fichier (aucun fichier caché) tel que :

  • /boot/efi/EFI/APPLE/EXTENSIONS/Firmware.scap

Quant à /boot/grub, les deux seules fichiers *.efi sont dans le répertoire x86_64 tel que :

  • /boot/grub/x86_64/grub.efi
  • /boot/grub/x86_64/core.efi
    L’un comme l’autre sont illisible simplement, j’entends par là avec les commandes cat ou more.

En résumé, dans /boot/ je n’ai que trois fichiers *.efi, ce que m’a confirmé un find :

  • /boot/efi/EFI/debian/grubx64.efi
  • /boot/grub/x86_64/grub.efi
  • /boot/grub/x86_64/core.efi

En tout cas, je ne vois aucun fichier efi qui correspondrait aux systèmes mac. Quant au fichier Firmware.scap, une rapide recherche m’apprend qu’il s’agit “en gros” de l’équivalent *.efi, mais pour mac, donc *.scap, que grub ne doit de toute façon pas savoir gérer, enfin j’imagine… (https://fileinfo.com/extension/scap)

Serait-il opportun de copier les fichiers *.efi actuellement utilisés de /System/Library/… sda2 et sda4 pour les ranger dans /boot/efi/EFI/APPLE/EXTENSIONS/ et adapter les scripts grub ?

Oui, en fait j’ai tord, mon linux est amorcé directement par son noyau.

grubx64.efi est la “core image” de GRUB au format EFI x86 64 bits qui est chargée par le firmware au démarrage comme spécifié dans l’entrée d’amorçage Boot000 qui est en premier dans l’ordre d’amorçage.
grub.efi et core.efi servent lors du processus d’installation du chargeur GRUB. L’un des deux est une copie (ou plutôt l’original) de grubx64.efi. Ils ne sont pas utilisés lors du processus de démarrage.

Il faudrait demander à la commande file ce qu’elle pense du contenu de ce fichier.

Je n’en vois pas l’intérêt puisque GRUB peut les lire directement depuis leurs partitions HFS+. Par contre il se peut que ces exécutables s’attendent à trouver d’autres fichiers dans le répertoire courant ou au voisinage et ne fonctionnent pas si tu ne copie que le fichier. D’autre part, il ne serait pas modifié en cas de mise à jour du fichier originel par Mac OS X, ce qui pourrait causer une incohérence, comme quand on copie la core image de GRUB à un autre emplacement.

En fait le noyau Linux est amorcé par GRUB. GRUB amorce les noyaux des autres systèmes Linux détectés de la même façon que le noyau du système qui l’a installé (contrairement à d’autres systèmes comme Windows qu’il amorce par chaînage de leurs chargeur respectifs). Il a visiblement cherché à faire de même avec Mac OS X en amorçant directement son noyau XNU/Mach avec ses commandes xnu_*, mais apparemment ça n’a pas marché. Peut-être que cette méthode ne fonctionne pas en mode EFI, mais encore une fois c’est pure supposition car je ne connais rien au Mac.

Ok, merci pour les explications.

# file Firmware.scap
Firmware.scap: data

C’est clairement différent de :

file grubx64.efi grubx64.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows.

Et, il n’y a à tout hasard aucun lien particulier entre ce fichier Firmware.scap et le fichier /etc/grub.d/30_uefi-firmware ?

Une dernière avant de considérer le sujet comme résolu, comment puis-je supprimer les entrées facultatives (car inutiles) du menu grub ? Puis-je simplement éditer le fichier grub.cfg pour les y retirer, sachant que je devrai le refaire après chaque update-grub ?

Je viens de virer manuellement les lignes concernées, elles venait du fichier /etc/grub.d/30_os-prober. Je ne sais pas si c’est bien propre comme méthode, peut-être que se serait un peu plus classe d’inhiber /etc/grub.d/30_os-prober et de lancer update-grub derrière, ce qui par ailleurs me priverait de répéter cette opération à chaque nouvelle commande update-grub, mais enfin, ça fonctionne, et c’est déjà pas si mal.

Il reste encore cette question, mais quelle qu’en soit la réponse l’objectif visé par ce sujet est pleinement atteint : sujet résolu.

Merci à tous et à toi PascalHambourg pour ton aide et tes connaissances.

Non. La fonction du script 30_uefi-firmware est d’ajouter une entrée au menu de GRUB pour entrer dans l’interface de configuration du firmware UEFI (similaire au “setup” du BIOS).

Exactement. Pour cela, tu peux soit désinstaller le paquet os-prober, soit ajouter une ligne dans le fichier /etc/default/grub pour désactiver l’appel à os-prober par grub-mkconfig (lui-même utilisé par update-grub pour générer le contenu de /boot/grub/grub.cfg) :

GRUB_DISABLE_OS_PROBER=true

Ok parfait. Je vais faire ça. Merci. J’ai du même coup déterrer un vieux sujet de moi qui traitait de cette question. En recherchant de l’aide sur un moteur de recherche on le trouvait facilement, et ça me gênait un peu car il n’apportait pas vraiment d’aide. Par ailleurs, il est encore visité de temps en temps. Voilà qui est changé.

Je suis surpris que rEFInd n’ait pas fonctionné, car bien que ne l’ayant jamais utilisé (je n’ai pas de Mac), j’en ai lu le plus grand bien (et j’ai beaucoup appris sur l’amorçage EFI en lisant le site de son auteur) et c’est ce que j’aurais suggéré s’il n’avait pas été possible d’amorcer Mac OS X à partir de GRUB.

Et bien avec le recul et mes souvenirs, je crois qu’il se passait pour refind et linux exactement ce qu’il s’est passé ici pour grub et mac : Refind installé depuis macOS gérait très bien les systèmes mac, mais pas le linux, et il aurait fallu faire pour refind ce que l’on a fait ici pour grub, “montrer manuellement le chemin de demarrage”.

PS : Au cas où il arriverait que la machine démarre avec d’autres disques présents (internes ou externes), il serait plus prudent d’utiliser les UUID des partitions comme GRUB le fait dans ses entrées de menu auto-générées, par exemple :

    insmod part_gpt
    insmod hfsplus
    set root='hd0,gpt2'
    if [ x$feature_platform_search_hint = xy ]; then
      search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2  6201e6e69aa6d78b
    else
      search --no-floppy --fs-uuid --set=root 6201e6e69aa6d78b
    fi

L’UUID est la chaîne de caractère à la fin des lignes search, qui doit correspondre à l’UUID de la partition affiché par blkid (pas le PARTUUID que GRUB ne semble pas savoir utiliser, ce qui est fort dommage à mon avis).

Autant en mode BIOS le disque de boot est toujours hd0, autant je ne peux garantir que c’est le cas en mode EFI, la notion même de disque de boot étant floue dans ce contexte.

Et bien justement, j’ai eu très peur lorsque j’ai fais la manipulation sur le macbook pro, car grub m’affichait une fin de non recevoir, il ne pouvait pas joindre la partition… tout simplement parce qu’effectivement, sur ce mac il ne s’agissait pas de hd0, qui n’existe pas, mais de hd1.

Ok, merci pour ton script, je vais le mettre en place avec mes UUID. Je vais essayer ça.

Ca fonctionne toujours, mais l’objectif visé est raté je crois. Grub m’annonce que l’uuid ne lui “parle” pas :

Error : No such device 0714e1c8-6a31-32ed-bfa3-371c784f3214

Cependant, le boot finit par se faire quand même, ça prend simplement 3 secondes de plus durant lesquels il y a cette phase d’erreur.

J’ai dû me tromper en intégrant le script, mais je ne vois pas comment. L’UUID est bien celui correspondant à la bonne partition, je l’ai intégré à la place des tiens pour chaque ligne search. Je ne peux pas avoir fait de faute de “recopiage”, il s’agit d’une copie, et c’est la première chose que j’ai vérifié ensuite. Voici le script au complet pour une entrée :

menuentry "Mac OS X - Lion - 10.7.5 - /dev/sda2" {
insmod part_gpt
insmod hfsplus
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
      search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 0714e1c8-6a31-32ed-bfa3-371c784f3214 
    else
      search --no-floppy --fs-uuid --set=root 0714e1c8-6a31-32ed-bfa3-371c784f3214
    fi
chainloader /System/Library/CoreServices/boot.efi
}

L’UUID présent dans l’entrée de menu générée automatiquement par update-grub avec os-prober avait une forme différente : 6201e6e69aa6d78b. C’est la première fois que je vois GRUB utiliser un UUID différent de celui rapporté par blkid. Ne connaissant rien au monde Mac et au système de fichiers HFS/HFS+, je n’ai pas la moindre idée de l’explication. Mais cela devrait mieux fonctionner avec ces UUID.

Oui, quand j’ai vu ton script, je me suis dit que tu avais des uuid bizarre, en tout cas différents de miens.

J’ai remplacé les uuid “réels” par ceux que grub génère via os-prober, et ça enlève la phase d’erreur : tout est à nouveau parfaitement fonctionnel.

Ce script permet donc à grub de chercher via l’uuid si sa recherche par dénomination hd0, hd1, ne fonctionne pas, c’est bien ça ?

En gros, oui. C’est au cas où le numéro du disque ou de la partition ne serait pas fiable.