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

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

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

Le disque virtuel initial (également appelé initdisk ou initrd) résout précisément les problèmes décrits ci-dessus. Le kernel Linux offre la possibilité d'avoir un petit système de files chargé sur un disque RAM et d'y exécuter des programmes avant que le système de files racine ne soit monté. Le chargement de 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 datatables du support de démarrage. Si le chargeur de démarrage est capable de charger le kernel, il peut également charger le disque virtuel initial. Des pilotes spéciaux ne sont pas requirejs.

Si / boot n'est pas une partition différente mais présente 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 kernel? Si vous pouvez accéder directement aux images, alors pourquoi avons-nous besoin des pilotes SCSI?

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

D'accord, je suppose, que vous utilisez GRUB ou GRUB2 comme bootloader pour l'explication. Tout d'abord, lorsque le BIOS accède à votre disque pour charger le chargeur de démarrage, il utilise ses routines embeddedes pour l'access au disque, qui sont stockées dans la célèbre interruption de 13h. Bootloader (et le kernel à la phase d'installation) utilisent ces routines lorsqu'ils accèdent au disque. Notez que le BIOS fonctionne en mode réel (16 bits), 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 + décalage , où l'adresse et l'offset du segment sont 16 bits, voir http://en.wikipedia.org/wiki/X86_memory_segmentation ). Ainsi, ces routines ne peuvent pas accéder à plus de 1 MiB de RAM, ce qui est une limitation ssortingcte et un inconvénient majeur.

Le BIOS charge le code du bootloader directement depuis le 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 le premier 32 KiB d'espace disque, appelé région de compatibilité DOS, soit à partir d'une adresse fixe du système de files. Il n'a pas besoin de comprendre le système de files pour le faire, car même si l'étape 1.5 est dans le système de files, il s'agit d'un 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'access au disque du BIOS.

entrer la description de l'image ici

Stage1.5 contient les utilitaires de système de files, de sorte qu'il peut lire le stage2 à partir du système de files (bien, il utilise toujours le BIOS 13h pour lire du disque à la RAM, mais maintenant il peut déchiffrer les informations du système de files sur les inodes etc. disque). Les anciens BIOS pourraient ne pas être en mesure d'accéder à l'set de la HD en raison des limitations de leur mode d'adressage de disque. Ils pourraient utiliser le système Cylinder-Head-Sector, incapable d'adresser plus de 8 Go d'espace disque : http://en.wikipedia.org org / wiki / Cylinder-head-secteur .

Stage2 charge le kernel dans la RAM (encore une fois, en utilisant les utilitaires de disque BIOS). Si c'est le kernel 2.6+, il y a aussi initramfs compilé dedans, donc pas besoin de le charger. Si c'est un kernel plus ancien, bootloader charge aussi l'image initrd autonome en memory, de sorte que le kernel puisse le monter et get des pilotes pour monter le système de files réel à partir du disque.

Le problème est que le kernel (et ramdisk) pèsent plus de 1 MiB, donc pour les charger dans la RAM, il faut charger le kernel au premier MiB, puis passer en mode protégé (32 bits), déplacer le kernel chargé en haute memory le premier 1 MiB pour le mode réel), puis revenir au mode réel (16 bits), ramener le disque dur du disque au premier 1 MiB (si c'est un initrd séparé et un kernel plus ancien), passer éventuellement en mode protégé (32 bits) mettez-le là où il est, revenez peut-être en mode réel (ou pas: https://stackoverflow.com/questions/4821911/does-grub-switch-to-protected-mode ) et exécutez le code du kernel. Avertissement: Je ne suis pas entièrement sûr de la rigueur et de l'exactitude de cette partie de la description.

Maintenant, lorsque vous exécutez le kernel, vous l'avez déjà et ramdisk chargé dans RAM par bootloader , de sorte que le kernel peut utiliser les utilitaires de disque de ramdisk pour monter votre système de files racine réel et y faire pivoter la racine. Les pilotes ramfs sont présents dans le kernel, afin de comprendre le contenu d'initramfs, bien sûr.

Je crois, cela se résume à ce que les fonctionnalités support bootloader particulier. Par exemple. il n'a pas besoin de connaître le système de files particulier de votre partition combinée (boot + root). Dans ce cas, il vous suffit de créer une partition de démarrage distincte en condition de fonctionnement avec votre bootloader et toute autre difficulté liée au assembly de votre partition racine sur le kernel et l'image initrd démarrée à partir de la partition de démarrage. Bootloader sait comment accéder aux périphériques SCSI (et à d'autres périphériques, selon le chargeur de démarrage utilisé) en utilisant ses propres pilotes ou en utilisant les routines du BIOS. De plus, il sait lire certains filesystems, etc.

Considérez par exemple. UEFI, où le firmware UEFI sait déjà comment accéder à la partition EFI, le lire et charger le kernel Linux à partir de là sans avoir besoin d'un bootloader intermédiaire. Dans ce cas, l'image linux vit séparée de la partition racine et le microprogramme UEFI ne doit pas connaître tous les filesystems exotiques pour y accéder. Je crois que la séparation des images "boot" de la partition "root" est très logique. Si ce n'est pas pour n'importe quoi d'autre alors c'est la nécessité en installant le chiffrage de système de files racine.

Juste pour memory, si un bootloader ne charge pas initrd, il vaut la peine de tester un autre bootloader; Je viens de rencontrer une situation comme celle-ci quand LILO a ignoré silencieusement un initrd de taille moyenne (<4Mb; un seul ext4 rootfs sur un SSD SATA; GPT) et GRUB 2.00 a réussi.

Le process 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)