Comment Linux charge-t-il l'image «initrd»?

13

J'ai essayé de comprendre le processus de démarrage, mais il y a juste une chose qui me dépasse.

Dès que le noyau Linux a été démarré et le système de fichiers racine (/) monté, les programmes peuvent être exécutés et d'autres modules du noyau peuvent être intégrés pour fournir des fonctions supplémentaires. Pour monter le système de fichiers racine, certaines conditions doivent être remplies. Le noyau a besoin des pilotes correspondants pour accéder au périphérique sur lequel se trouve le système de fichiers racine (en particulier les pilotes SCSI). Le noyau doit également contenir le code nécessaire pour lire le système de fichiers (ext2, reiserfs, romfs, etc.). Il est également envisageable que le système de fichiers racine soit déjà crypté. Dans ce cas, un mot de passe est nécessaire pour monter le système de fichiers.

Le disque virtuel initial (également appelé initdisk ou initrd) résout précisément les problèmes décrits ci-dessus. Le noyau Linux offre la possibilité d'avoir un petit système de fichiers chargé sur un disque RAM et d'y exécuter des programmes avant le montage du système de fichiers racine réel. Le chargement d'initrd est géré par le chargeur de démarrage (GRUB, LILO, etc.). Les chargeurs de démarrage n'ont besoin que de routines BIOS pour charger les données à partir du support de démarrage. Si le chargeur de démarrage est capable de charger le noyau, il peut également charger le disque virtuel initial. Des pilotes spéciaux ne sont pas nécessaires.

Si / boot n'est pas une partition différente, mais est présent dans la partition /, le chargeur de démarrage ne devrait-il pas avoir besoin des pilotes SCSI pour accéder à l'image «initrd» et à l'image du noyau? Si vous pouvez accéder directement aux images, alors pourquoi avons-nous besoin exactement des pilotes SCSI ??

rpthms
la source

Réponses:

20

Nighpher, je vais essayer de répondre à votre question, mais pour une description plus complète du processus de démarrage, essayez l' article IBM .

Ok, je suppose que vous utilisez GRUB ou GRUB2 comme chargeur de démarrage pour des explications. Tout d'abord, lorsque le BIOS accède à votre disque pour charger le chargeur de démarrage, il utilise ses routines intégrées pour l'accès au disque, qui sont stockées dans la célèbre interruption de 13h. Le chargeur de démarrage (et le noyau lors de la phase d'installation) utilisent ces routines lorsqu'ils accèdent au disque. Notez que le BIOS fonctionne en mode réel (16 bits) du processeur, donc il ne peut pas adresser plus de 2 ^ 20 octets de RAM (2 ^ 20 pas 2 ^ 16 car chaque adresse en mode réel est composée de segment_address * 16 + offset , où l'adresse de segment et le décalage sont tous deux de 16 bits, voir http://en.wikipedia.org/wiki/X86_memory_segmentation ). Ainsi, ces routines ne peuvent pas accéder à plus de 1 Mo de RAM, ce qui constitue une limitation stricte et un inconvénient majeur.

Le BIOS charge le code du chargeur de démarrage directement à partir du MBR - les 512 premiers octets de votre disque et l'exécute. Si vous utilisez GRUB, ce code est GRUB stage 1. Ce code charge GRUB stage 1.5, qui se trouve soit dans les 32 premiers Ko d'espace disque, appelé région de compatibilité DOS, soit à partir d'une adresse fixe du système de fichiers. Il n'a pas besoin de comprendre le système de fichiers pour ce faire, car même si l'étape 1.5 est dans le système de fichiers, c'est du code "brut" et peut être directement chargé dans la RAM et exécuté: http://www.pixelbeat.org/ docs / disque / . La charge de stage1.5 du disque vers la RAM utilise les routines d'accès au disque du BIOS.

entrez la description de l'image ici

Stage1.5 contient les utilitaires du système de fichiers, afin qu'il puisse lire le stage2 du système de fichiers (enfin, il utilise toujours le BIOS 13h pour lire du disque vers la RAM, mais maintenant il peut déchiffrer les informations du système de fichiers sur les inodes, etc. et obtenir le code brut de la disque). Les BIOS plus anciens peuvent ne pas être en mesure d'accéder à l'ensemble du disque dur en raison des limitations de leur mode d'adressage de disque - ils peuvent utiliser le système Cylinder-Head-Sector, incapable de traiter plus de 8 premiers Go d'espace disque: http: //en.wikipedia. org / wiki / Secteur-culasse .

Stage2 charge le noyau dans la RAM (à nouveau, en utilisant les utilitaires de disque du BIOS). S'il s'agit d'un noyau 2.6+, il contient également des initramfs compilés, donc pas besoin de le charger. S'il s'agit d'un noyau plus ancien, le chargeur de démarrage charge également une image initrd autonome dans la mémoire, afin que le noyau puisse le monter et obtenir des pilotes pour le montage du système de fichiers réel à partir du disque.

Le problème est que le noyau (et le disque virtuel) pèsent plus de 1 Mio, donc pour les charger dans la RAM, vous devez charger le noyau au premier 1 Mio, puis passer en mode protégé (32 bits), déplacer le noyau chargé en haute mémoire (gratuit le premier 1 Mio pour le mode réel), puis revenir à nouveau en mode réel (16 bits), obtenir le disque virtuel du disque au premier 1 Mio (si c'est un initrd séparé et un noyau plus ancien), éventuellement basculer à nouveau en mode protégé (32 bits), placez-le à sa place, revenez éventuellement en mode réel (ou non: /programming/4821911/does-grub-switch-to-protected-mode ) et exécutez le code du noyau. Avertissement: je ne suis pas entièrement sûr de l'exhaustivité et de l'exactitude de cette partie de la description.

Maintenant, lorsque vous exécutez enfin le noyau, vous l'avez déjà et le ramdisk chargé dans la RAM par le chargeur de démarrage , afin que le noyau puisse utiliser les utilitaires de disque de ramdisk pour monter votre véritable système de fichiers racine et pivoter la racine vers lui. Les pilotes ramfs sont présents dans le noyau, il peut donc bien sûr comprendre le contenu d'initramfs.

Boris Burkov
la source
Le bootlader ne peut-il pas simplement charger le noyau en morceaux, au lieu de sauter en mode protégé ?? Et quel est le besoin de libérer ce 1 Mo .. (Désolé .. je ne pouvais pas comprendre cela ..)
rpthms
Le besoin de libérer d'abord 1 Mo est le suivant: le chargeur de démarrage ne peut accéder à votre disque dur qu'en mode réel, car il y accède avec les utilitaires du BIOS, qui sont en mode réel (ils fonctionnent sur des arguments 16 bits et utilisent des opérations 16 bits). Le mode réel ne voit tout simplement pas de RAM sauf par 1 premier Mo. Mais vous devez charger le noyau + initramfs dans la RAM et ils prennent environ 5 Mo d'espace dans la RAM. Ces utilitaires du BIOS ne seront tout simplement pas en mesure de compresser 5 Mo dans le premier 1 Mo. Ainsi, le chargeur de démarrage doit les copier du disque vers le premier 1 Mo, puis passer en mode protégé et les déplacer de la première RAM de 1 Mo vers la RAM supérieure. Est-ce plus clair maintenant? :)
Boris Burkov
1
L'ensemble de la scène 1 / 1,5 / 2 est un héritage grub.
psusi
1
@CMCDragonkai Oui, le chargeur de démarrage stage2 est dans le système de fichiers (à savoir, dans la /bootpartition). Le noyau n'est pas chargé à ce stade - c'est l'étape 1.5 de grub, qui accède à l'étape 2 dans le /bootsystème de fichiers (par exemple dans le /boot/grubfichier) via ses pilotes de système de fichiers minimalistes. Le noyau pourra également lire à partir de la /bootpartition, mais cela se produira plus tard, après l'exécution du code grub2 et le chargement du noyau et après que le noyau a lu initramfs. Parlez-vous init.shdes initramfs? Il réside dans la /bootpartition de votre disque dur, puis stage2 de grub le place dans la RAM et le noyau le lit à partir de la RAM.
Boris Burkov
1
Initrd devait être un fichier séparé. Les initramfs plus récents peuvent être liés au noyau, mais ce n'est pas obligatoire - ils peuvent également être chargés dans un fichier séparé par le chargeur de démarrage. Étant donné que le fichier initramfs est défini comme une séquence d'archives cpio, certains chargeurs de démarrage (par exemple iPXE) autorisent même plusieurs fichiers initramfs, qui seront chargés en mémoire les uns après les autres. De plus, certaines distributions Linux utilisent des noms de fichiers de style initrd pour une compatibilité ascendante, bien que la technologie réellement utilisée soit désormais initramfs.
telcoM
1

Je crois que cela se résume aux fonctionnalités que prend en charge notamment le chargeur de démarrage. Par exemple. il n'a pas besoin de connaître le système de fichiers particulier de votre partition combinée (démarrage + racine). Dans ce cas, vous créez simplement une partition de démarrage séparée dans des conditions telles qu'elle fonctionne avec votre chargeur de démarrage, et toute autre complexité de la façon de monter votre partition racine est laissée sur le noyau et l'image initrd démarrée à partir de la partition de démarrage. Le chargeur de démarrage sait comment accéder aux périphériques SCSI (et à d'autres périphériques également, selon le chargeur de démarrage utilisé) en utilisant ses propres pilotes ou en utilisant des routines BIOS. De plus, il sait lire certains systèmes de fichiers, etc.

Considérez par exemple. Mode de démarrage UEFI, où le firmware UEFI sait déjà comment accéder à la partition EFI, la lire et charger le noyau linux à partir de là sans avoir besoin d'un chargeur de démarrage intermédiaire. Dans ce cas, l'image Linux vit séparée de la partition racine et le firmware UEFI n'a pas besoin de connaître tous les systèmes de fichiers exotiques pour y accéder. Je pense que la séparation des images de "démarrage" de la partition "racine" est tout à fait sensée. Si ce n'est pour rien d'autre, c'est une nécessité lors de la configuration du cryptage du système de fichiers racine.

Miroslav Koškár
la source
0

Pour mémoire, si un chargeur de démarrage ne charge pas initrd, il vaut la peine de tester un autre chargeur de démarrage; Je viens de rencontrer une situation comme celle-ci lorsque LILO a silencieusement ignoré un initrd correctement spécifié de taille moyenne (<4 Mo; rootfs ext4 unique sur un SSD SATA; GPT) et GRUB 2.00 a réussi.

Le processus de démarrage s'est terminé rapidement avec un

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)
Michael Shigorin
la source