polyzargone
Alors voici une rallonge « spéculative » (je n'ai aucune formation informatique, mais classique : philosophie > logique aristotélicienne et mathématique => j'applique donc un raisonnement tout ce qu'il y a de non-spécialisé aux objets informatiques).
Le
boot_loader : boot.efi (localisé at:
/System/Library/CoreServices) est un fichier exécutable de type spécial, en ce qu'il est exécutable par l'
EFI. On peut donc le considérer comme une « application de l'
EFI ».
Cette application n'est pas cantonnée mécaniquement au mode d'emploi de son code, mais a la propriété de pouvoir recevoir des
instructions supplémentaires de la part de l'
EFI. En effet, l'
EFI, après vérification du hardware (
POST) > commence toujours par visiter la
NVRAM pour y lire les instructions en place, genre
boot_flags. Le
SIP, notamment, consiste en une suite de
6 flags en
NVRAM qui sont chargés par l'
EFI. Par suite, l'
EFI ne se contente pas de lancer l'application qu'est le
boot.efi > mais elle « passe » (transmet) à cette application les
flags de la
NVRAM => il s'agit donc d'une «
implémentation » en amont du code du
boot.efi.
----------
À présent > une spécificité d'
OS X >
macOS est que ce Système ne démarre pas régulièrement sur l'
original du
kernel (at:
/System/Library/Kernels/kernel) > mais sur un
clone du code de ce
kernel recelé dans un cache de démarrage
prelinkedkernel (at:
/System/Library/PrelinkedKernels/prelinkedkernel). Le
kernel original sert de paradigme pour la constitution du cache de démarrage.
La fonction basique du
boot.efi est de
démarrer le
kernel par l'exécution de son code et de déclencher le processus d'
injection des
kexts dans l'espace du
kernel par transmission du bloc d'adresses d'extensions recelé dans le cache
prelinkedkernel. Mais > dans la mesure où le
boot.efi, en tant qu'application de l'
EFI, a reçu une implémentation de
flags de la part de l'
EFI > le
boot.efi assure le rôle supplémentaire de passation de ces
flags au
kernel : c'est donc ici un rôle de « rouage de transmission ». C'est ainsi, par exemple, que les
flags du
SIP se trouvent passés au
kernel au démarrage. Je pense que cette transmission « supplémentaire » s'opère
au démarrage du
kernel par le
boot.efi > avant même le processus d'injection.
----------
Étant donné ce court aperçu de la séquence de pré-boot > la question spéculative passionnante est : que se passe-t-il quand l'exécution du
boot_loader boot.efi par l'
EFI se trouve «
interceptée » par le
boot_loader d'un gestionnaire de démarrage comme le
bootx64.efi de «
rEFInd» ? Sachant que l'
EFI quitte classiquement, en tant que processus logiciel, après l'exécution de l'application :
boot.efi > je présume qu'on peut extrapoler cette séquence à celle de l'exécution du
boot_loader de «
rEFInd» : cette application tierce de l'
EFI démarrée > l'
EFI quitte la scène.
Cette analogie fonctionnelle des
boot_loaders permet d'induire que le
boot_loader de «
rEFInd» est capable, comme le
boot.efi orthodoxe, de recevoir l'
implémentation par l'
EFI de
flags de la
NVRAM. À supposer qu'aucun
filtre de ces
flags ne soit activé dans le programme du
boot_loader de «
rEFInd». Ainsi, dans l'environnement de «
Yosemite 10.10» (tristement notoire pour l'introduction des
flags du
kext_signing en
NVRAM) > démarrer cet OS par l'intermédiaire du
boot_loader de «
rEFInd» et pas directement par le
boot.efi > avait une admirable conséquence : les
flags du
kext_signing (supposés présents en
NVRAM) n'étaient pas reçus de la part de l'
EFI par le
boot_loader de «
rEFInd» > mais
échappés > ce qui fait qu'on pouvait bidouiller des
kexts Apple sans qu'aucune vérification d'intégrité tâtillonne ne soit opérée.
Ce petit point curieux démontre ceci : un
boot_loader de tierce partie comme celui de «
rEFInd» possède une « autonomie » logicielle relative par rapport au déterminisme strict du
boot_loader boot.efi orthodoxe. Autonomie confirmée par le fait que, le
boot_loader de «
rEFInd» activé > le choix du mode de démarrage d'un OS ciblé se trouve ouvert (
safe mode,
single user,
verbose etc.). C'est dans le volume
EFI de l'
ESP (
EFI_System_Partition :
disk0s1 pour un disque unique) que résident les dossiers de boot de «
rEFInd».
----------
Admis l'état de choses :
boot_loader de «
rEFInd» démarré et processus de l'
EFI quitté > comment va s'opérer le démarrage du Système ciblé ? - ma faculté spéculative avait envisagé 2 options : soit le
boot_loader de «
rEFInd» adressait
directement le
prelinkedkernel de démarrage > soit le
boot_loader de «
rEFInd» exécutait le
boot.efi du Système-cible - à charge pour ce dernier de démarrer le
kernel du
prelinkedkernel (exclue la possibilité d'une double action > car le
kernel ne peut pas être démarré 2 fois > mais
une seule fois : soit par un
boot_loader > soit par l'autre).
Je pense que c'est la
seconde option qui est vraie : le
boot_loader de «
rEFInd» tient le rôle exécutif de l'
EFI pour le
boot_loader boot.efi régulier et ne se
susbtitue pas à lui pour charger directement le
prelinkedkernel. Argument simple : étant donné qu'un même
boot_loader de «
rEFInd» est capable de lancer toute sortes de versions de
macOS (de «
Snow Léopard» à «
Sierra» sur mon
MacBook Pro 17" i7 2,5 GHz Late_2011) > impliquant des
kernels d'architecture variée (
mach_kernel >
kernel) --> il me paraît difficile à concevoir que son code puisse gérer un pareil différentiel. Argument « légaliste » : un
boot_loader de tierce partie fonctionnant en
substitution du
boot_loader Apple réglementaire > équivaudrait à un remplacement logiciel incriminable.
À supposer donc ma conjecture valide : le
boot_loader de «
rEFInd» jouant le rôle de
relai exécutif de l'
EFI pour l'exécution spécifique du
boot_loader boot.efi orthodoxe --> on aurait donc la chaîne :
EFI >
NVRAM >
boot_loader tiers >
boot.efi >
prelinkedkernel.
----------
Supposons à présent que parmi les ressources de l'application :
boot_loader tiers dans le volume de l'
ESP > il y ait des
kexts à faire injecter dans l'espace du
kernel > et supposons toujours que le
boot_loader tiers ait pour cible exclusive l'exécution du
boot_loader boot.efi orthodoxe qu'il ne peut pas remplacer > et gardons toujours présente à l'esprit l'idée que le
kernel ne peut pas être démarré 2 fois > mais
une seule fois > le seul
kernel adressable étant le
clone du code du
kernel recelé par le
prelinkedkernel.
Alors peut se concevoir la séquence suivante : le
boot_loader tiers (on dira celui de «
Clover» dont je ne sais rien mais que je reconstruis en imagination par extrapolation de celui de «
rEFInd») > ne peut absolument
pas injecter directement et préliminairement les
kexts supplémentaires qui sont recelées dans ses dossiers de ressources sur l'
ESP > car pour ce faire > le
kernel devrait être déjà démarré auparavant > afin qu'elles soient injectées dans son espace. Mais > si c'est bien le
boot_loader boot.efi qui est en charge de ce lancement du
kernel > sans avoir encore été exécuté par le
boot_loader tiers > alors le
boot_loader tiers ne peut injecter aucune kext par lui-même.
Ce qu'il peut faire > c'est : à l'exécution du
boot_loader boot.efi > lui passer comme
implémentation le
tableau d'adresses des
kexts tierces recelées dans le volume de l'
ESP (NB. savoir qu'au pré-boot >
tous les volumes montables sur toutes les partitions de disques sont
montés et
adressables, le volume
EFI de l'
ESP compris). Donc le
boot_loader tiers passerait ce
tableau au
boot_loader boot.efi au même titre que les
flags reçus de l'
EFI.
Ledit
boot_loader boot.efi se trouverait donc
implémenté dans son code de
flags de la
NVRAM et du
tableau d'adresses de
kexts transmis par le
boot_loader tiers qui devance son exécution. Conséquence : le
boot_loader boot.efi ainsi
implémenté >
démarrerait le
kernel du
prelinkedkernel > lui passerait au moment même de ce démarrage les
flags de la
NVRAM de provenance
EFI et le tableau des
kexts de l'
ESP de provenance
boot_loader tiers > puis lirait le
bloc des adresses de
kexts inclus dans le
prelinkedkernel pour le passer régulièrement au
kernel.