Pourquoi le mode de démarrage sécurisé de Mac serait-il plus lent que le démarrage standard ?


Dans le processus normal de démarrage la première fois que Mac OS X (ou macOS, maintenant) ou iOS démarre, le chargeur de démarrage charge le noyau, puis il charge un certain nombre de KEXTs.

Ces KEXTs sont un ensemble d'extensions du noyau, constituées principalement de pilotes et d'autres codes qui mettent en œuvre les classes IOKit et les extensions du noyau, notamment les extensions utilisées pour la signature du code, le KEXT DontStealMacOS qui vérifie que la plateforme sur laquelle il est exécuté est un "Genuine Macintosh" (matériel fabriqué par Apple), et ainsi de suite.


Dans le cadre de ce processus de démarrage initial, une image est créée du noyau avec toutes les extensions qui sondent vrai comme étant présentes, et toutes les extensions qui sondent faux comme n'étant pas présentes.

Par exemple, puisque le même noyau peut fonctionner sur différentes plateformes Apple avec différents ensembles de pilotes pour différents matériels.

Il n'y a guère de sens à charger un pilote UHCI ou EHCI pour l'USB, si le matériel ne supporte que le seul XHCI avancé ; de même, il n'y a pas de sens à charger le pilote nVidia pour un MacBook Pro particulier, si le matériel actuel ne possède pas cette puce parce que c'est un MacBook Air.

Un autre composant est le support direct de la carte mère pour le stepping du CPU, les vitesses d'horloge de la RAM supportées, le chipset de support (Haswell, etc.), et ainsi de suite ; ce code particulier vit dans le PE ou PlatformExpert, qui est unique pour chaque SKU de plateforme matérielle d'ordinateur Apple.

Donc au final, il y a beaucoup de composants optionnels qui sont chargés, mais un sacré paquet d'autres qui ne sont pas chargés.

Mais il faut essayer chacun d'entre eux pour voir s'il s'adapte.

Après que tout soit mis en place, l'une des premières choses qui se produit après le démarrage est qu'une version post-linkée du noyau avec tous les KEXTs qui sont chargés pour cette plateforme est créée.

C'est ce qu'on appelle le "kextcache" - qui porte le même nom que le programme qui s'exécute pour générer l'image.

Après cela, l'ordinateur, lorsqu'il démarre, charge directement le kextcache, et démarre fantastiquement vite (en fait, cela pourrait être fait plus rapidement en triant les pages d'images dans l'ordre où elles seront demandées, et juste commencer immédiatement à exécuter le code ; le kextcache ne fait pas cela).

Lorsque vous démarrez en "mode sans échec", ce qui se passe, c'est que les pilotes optionnels (non strictement nécessaires, et non tiers) ne sont pas chargés - mais il saute le kextcache - dont il craint qu'il soit corrompu, car vous démarrez en "mode sans échec" pour une raison.

Alors, il doit aller charger mach_kernel, puis il doit charger les KEXTs potentiellement nécessaires.

Ce qui signifie qu'il doit repasser par toutes les étapes, ce qui est sensiblement plus lent que de charger le kextcache.

Les gens ne le remarquent généralement pas au premier démarrage, parce que pendant que le système démarre la première fois, il fait la "Happy First Time Boot Greeting Dance™", qui est suffisamment distrayante pour que le délai de démarrage soit caché à l'observation de l'utilisateur.

En pratique, une partie du travail est effectuée à l'usine pendant la finalisation du démarrage dans le cadre du burn-in, mais il y a généralement une installation tardive pour que les nouveaux ordinateurs Apple soient livrés avec la version la plus récente de l'OS (auquel cas, lorsque l'utilisateur le démarre, il effectue la création du kextcache).

Pour iOS et les autres appareils qui ne sont pas Mac OS X/macOS, le kextcache est pré-généré, et inclus dans l'image système ("No User Serviceable Parts Inside™"), puisque la configuration matérielle ne changera pas, et que le facteur ne va pas faire une installation late-binding du nouvel OS.

Pour ces appareils, il est également habituel de désactiver certaines interfaces du noyau qui sont utilisées pour charger ou décharger des modules, lier des modules contre le noyau, et ainsi de suite, pour éviter qu'elles soient facilement piratées.

Notez que, puisque les API internes et exposées sont les mêmes, il est possible de pirater la table sysent[] sur un appareil iOS dans le cadre d'un jailbreak pour les réactiver, si vous êtes un développeur de noyau très expérimenté et que vous avez accès à un exploit de mémoire du noyau qui n'implique pas d'accéder au premier port Mach pour l'espace d'adressage virtuel du noyau.

Dans tous les cas, la réponse très courte est :

Lorsque vous démarrez en "Safe Mode", il charge les composants du noyau individuellement, et teste-charge beaucoup de composants inutiles pour votre plateforme particulière et les décharge par la suite, au lieu d'utiliser l'image kextcache pré-optimisée.