Comment un noyau monte-t-il la partition racine?

29

Ma question concerne le démarrage d'un système Linux à partir d'une partition / boot distincte. Si la plupart des fichiers de configuration se trouvent sur une partition / séparée, comment le noyau la monte-t-il correctement au démarrage?

Toute élaboration à ce sujet serait formidable. J'ai l'impression de manquer quelque chose de basique. Je m'intéresse principalement au processus et à l'ordre des opérations.

Merci!

EDIT: Je pense que ce que je devais demander était plus dans le sens du fichier de développement utilisé dans le paramètre du noyau racine. Par exemple, disons que je donne mon paramètre racine en tant que root = / dev / sda2. Comment le noyau a-t-il un mappage du fichier / dev / sda2?

M. Shickadance
la source
Bien que les personnes ci-dessous couvrent initrd, il y a peu de discussions sur la raison pour laquelle initrd est utilisé. Mon impression est que c'est parce que des distributions comme Debian veulent utiliser un noyau sur de nombreuses machines différentes de la même architecture, mais éventuellement sur un matériel très différent. Ceci est rendu possible par la modularisation du support matériel via les modules du noyau. L'initrd ne nécessite pas beaucoup de support matériel pour démarrer, et une fois qu'il le fait, il charge les modules matériels nécessaires pour continuer. Des précisions / corrections à ce sujet sont appréciées.
Faheem Mitha
Vous ne pouvez pas monter / boot sans avoir monté / d'abord, car il n'y a pas de répertoire / boot sans /.
psusi

Réponses:

20

Linux démarre initialement avec un ramdisk (appelé an initrd, pour "INITial RamDisk") comme /. Ce disque en a juste assez pour pouvoir trouver la vraie partition racine (y compris tous les pilotes et modules de système de fichiers requis). Il monte la partition racine sur un point de montage temporaire sur le initrd, puis invoque pivot_root(8)pour échanger les points de montage racine et temporaire, laissant le initrden position à umountmodifier et le système de fichiers racine réel activé /.

geekosaure
la source
2
Et si vous n'avez pas d'initrd comme LFS (linuxfromscratch.org)?
M. Shickadance
@M. Shickadance: N'ayant pas examiné la façon dont LFS fait les choses, je suppose qu'ils s'assurent que le noyau a tous les modules nécessaires compilés (ou chargés via GRUB 2, cette possibilité est suffisamment nouvelle pour que peu de distributions ne l'aient encore remarqué), donc il peut démarrer sur la partition racine réelle.
geekosaur
4
@m. Shickadance. Ce n'est pas seulement LFS qui n'a pas d'initrd. Quiconque compile son propre noyau a la possibilité de ne pas utiliser d'initrd, ce que je fais sur Gentoo.
jonescb
1
@Faheem: les modules grub2 ne sont pas les mêmes que les modules du noyau. Je vois une certaine capacité pour grub2 de charger les modules du noyau, mais je ne sais pas si cela fonctionnera pour le noyau Linux ou seulement pour * BSD (où le chargeur de démarrage chargeant les modules du noyau est normal). Je soupçonne que le noyau doit apprendre où trouver la carte d'adresses pour les modules chargés, et tout le monde doit passer à grub2 (grub1 est toujours standard dans certaines distributions).
geekosaur
1
L'initrd a été remplacé par initramfs, puisque pivot_root était considéré comme un hack sale.
psusi
41

Dans les temps anciens, le noyau était codé en dur pour connaître le nombre majeur / mineur de périphérique de la racine fs et monté ce périphérique après avoir initialisé tous les pilotes de périphériques, qui ont été intégrés au noyau. L' rdevutilitaire peut être utilisé pour modifier le numéro de périphérique racine dans l'image du noyau sans avoir à le recompiler.

Finalement, les chargeurs de démarrage sont arrivés et pouvaient passer une ligne de commande au noyau. Si l' root=argument était passé, cela indiquait au noyau où se trouvait la racine fs au lieu de la valeur intégrée. Les pilotes devaient accéder à ce qui devait encore être intégré dans le noyau. Bien que l'argument ressemble à un nœud de périphérique normal dans le /devrépertoire, il n'y a évidemment pas de /devrépertoire avant que le fs racine ne soit monté, donc le noyau ne peut pas rechercher un nœud de développement là-bas. Au lieu de cela, certains noms de périphériques bien connus sont codés en dur dans le noyau afin que la chaîne puisse être traduite en numéro de périphérique. Pour cette raison, le noyau peut reconnaître des choses comme /dev/sda1, mais pas des choses plus exotiques comme /dev/mapper/vg0-rootou un UUID de volume.

Plus tard, le initrdest entré en scène. Avec le noyau, le chargeur de démarrage chargerait l' initrdimage, qui était une sorte d'image de système de fichiers compressée (image extz gzippée, image romfs gzippée, squashfs est finalement devenue dominante). Le noyau décompresserait cette image dans un disque virtuel et monterait le disque virtuel en tant que racine fs. Cette image contient des pilotes et des scripts de démarrage supplémentaires au lieu d'un vrai init. Ces scripts de démarrage ont effectué diverses tâches pour reconnaître le matériel, activer des éléments tels que les tableaux RAID et LVM, détecter les UUID et analyser la ligne de commande du noyau pour trouver la vraie racine, qui pourrait maintenant être spécifiée par l'UUID, l'étiquette de volume et d'autres choses avancées. Il a ensuite monté le vrai root fs dans /initrd, puis exécuté l' pivot_rootappel système pour que le noyau permute /et/initrd, puis exécutez /sbin/initsur la vraie racine, qui démonterait /initrdet libérerait alors le ramdisk.

Enfin, nous avons aujourd'hui le initramfs. Ceci est similaire à initrd, mais au lieu d'être une image de système de fichiers compressée qui est chargée dans un disque virtuel, il s'agit d'une archive cpio compressée. Un tmpfs est monté en tant que racine et l'archive y est extraite. Au lieu d'utiliser pivot_root, qui était considéré comme un hack sale, les initramfsscripts de démarrage montent la vraie racine dans /root, suppriment tous les fichiers dans la racine tmpfs, puis chrootdans /rootet exécutent /sbin/init.

psusi
la source
1
Après le chroot, les tmpfs sont-ils automatiquement démontés? Cela disparaît-il simplement?
jiggunjer
@jiggunjer, non, il est toujours là, il est juste vide (en plus de contenir le répertoire / root), et n'est plus utilisé.
psusi
J'ai appris quelque chose de nouveau sur chaque itération de root fs que vous avez mentionnée. Très bonne réponse!
jpaugh
3

On dirait que vous demandez comment le noyau "sait" quelle partition est la partition racine, sans accès aux fichiers de configuration sur / etc.

Le noyau peut accepter des arguments de ligne de commande comme n'importe quel autre programme. GRUB, ou la plupart des autres chargeurs de démarrage, peut accepter des arguments de ligne de commande comme entrée utilisateur, ou les stocker et rendre diverses combinaisons d'arguments de ligne de commande disponibles via un menu. Le chargeur de démarrage transmet les arguments de ligne de commande au noyau lorsqu'il le charge (je ne connais pas le nom ou la mécanique de cette convention, mais c'est probablement similaire à la façon dont une application reçoit les arguments de ligne de commande d'un processus appelant dans un noyau en cours d'exécution).

L'une de ces options de ligne de commande est root, où vous pouvez spécifier le système de fichiers racine, c'est-à-dire root=/dev/sda1.

Si le noyau utilise un initrd, le chargeur de démarrage est responsable de dire au noyau où il se trouve, ou de placer l'initrd dans un emplacement mémoire standard (je pense) - c'est au moins la façon dont cela fonctionne sur mon Guruplug.

Il est tout à fait possible de ne pas en spécifier un, puis de paniquer votre noyau immédiatement après avoir commencé à vous plaindre qu'il ne trouve pas de système de fichiers racine.

Il pourrait y avoir d'autres façons de passer cette option au noyau.

LawrenceC
la source
3
C'est la bonne explication quand il n'y a pas d'initrd / initramfs, mais il manque une pièce du puzzle. Normalement, le noyau identifie un périphérique, par exemple /dev/sda1parce qu'il s'agit d'une entrée dans un système de fichiers. Vous pourriez le faire cp -p /dev/sda1 /tmp/fooet /tmp/fooreprésenteriez le même appareil. Sur la ligne de commande du noyau, le noyau utilise un analyseur intégré qui suit la convention de dénomination de périphérique habituelle: sda1signifie la première partition du premier disque de type SCSI.
Gilles 'SO- arrête d'être méchant'
@Gilles donc les noyaux modernes ne peuvent toujours pas gérer le montage d'un volume basé sur UUID? sans initrdou initramfsje veux dire. Ce doit être une "simple" partition sous la /dev/sdxforme?
jiggunjer
1
@jiggunjer Les noyaux modernes prennent en charge la recherche d'un volume par UUID. Tu vois init/do_mounts.c.
Gilles 'SO- arrête d'être méchant'
1

Grub monte la /bootpartition puis exécute le noyau. Dans la configuration de Grub, il indique au noyau quoi utiliser comme périphérique racine.

Par exemple dans Grub's menu.lst:

kernel /boot/linux root=/dev/sda2
jonescb
la source
1

Allez, GRUB ne "monte" pas / boot, il lit juste 'menu.lst' et certains modules, il ne fait pas non plus partie du noyau LINUX. Lorsque vous appelez le noyau, vous passerez un argument "root" avec la partition root. Au pire, le noyau sait que juste / boot a été monté (LOL).

Suivant: geekosaur a raison, Linux utilise un disque virtuel initial au format d'image compressée, puis monte le véritable système de fichiers racine en appelant pivot_root. Linux démarre donc à partir d'une image, puis à partir de votre lecteur de disque local.

D4RIO
la source
1
Grub a certainement la possibilité de «monter» un système de fichiers, en particulier dans grub2. Bien sûr, tout ce qu'il est capable de / faire / avec lui est de chercher des noyaux amorçables d'une bande ou d'une autre, mais cela continue de monter. De plus, Linux ne nécessite pas d' initrd sauf si votre noyau compile des pilotes cruciaux pour votre disque dur en tant que modules.
Shadur
5
ibm.com/developerworks/linux/library/l-linuxboot Ceci est un résumé assez concis de ce que fait le noyau Linux lors du démarrage.
jsbillings
2
@Shadur, à partir de la page de manuel de montage : tous les fichiers accessibles dans un système Unix sont organisés dans une grande arborescence, la hiérarchie des fichiers, enracinée dans /. Ces fichiers peuvent être répartis sur plusieurs appareils. La commande mount sert à attacher le système de fichiers trouvé sur un périphérique à la grande arborescence de fichiers. - Étant donné que les systèmes de fichiers utilisés par GRUB ne sont pas attachés à la hiérarchie des fichiers, ce n'est PAS un montage .
D4RIO
1
@Shadur, BTW: Il est évident qu'initrd n'est pas nécessaire car il s'agit simplement d'un autre système de fichiers racine, mais il est généralement utilisé comme petite racine au démarrage, car le noyau charge le nécessaire pour démarrer, puis démarre et enfin charge tout le reste.
D4RIO
1
@ d4rio Ils sont montés par GRUB, pas par linux - cela devient plus facile à comprendre lorsque vous considérez grub comme un système d'exploitation micro-noyau propre plutôt qu'un simple chargeur de démarrage.
Shadur
1

Le chargeur de démarrage, que ce soit grub ou lilo ou autre, indique au noyau où chercher avec l' root=indicateur, et charge éventuellement un premier disque virtuel en mémoire via initrdavant de démarrer le noyau.

Le noyau se charge ensuite, teste ses pilotes de matériel et de périphérique et recherche dans le système ce qu'il peut voir (vous pouvez consulter ces informations de diagnostic en tapant dmesg; de nos jours, il défile probablement trop rapidement pour être vu) puis tente de monter la partition mentionnée dans le root=paramètre.

Si un initrd est présent, il est monté en premier et tous les modules / pilotes de périphérique qu'il contient sont chargés et testés avant le montage du système de fichiers racine. De cette façon, vous pouvez compiler les pilotes de vos disques durs sous forme de modules et toujours pouvoir démarrer.

Shadur
la source