Autant que je sache, initrd
agit comme un périphérique bloc, nécessitant ainsi un pilote de système de fichiers (tel que ext2
). Le noyau doit avoir au moins un module intégré pour la détection du système de fichiers de initrd
. Dans cet article, Introduction à initramfs, un nouveau modèle pour les disques RAM initiaux , il est écrit que:
Mais les disques virtuels ramassent encore plus de mémoire en raison de la mise en cache. Linux est conçu pour mettre en cache tous les fichiers et les entrées de répertoire lues ou écrites pour bloquer les périphériques, donc Linux copie les données depuis et vers le disque virtuel dans le "cache de page" (pour les données de fichier) et le "cache de dentry" (pour les entrées de répertoire ). L'inconvénient du ramdisk prétendant être un bloc de périphérique est-il traité comme un périphérique de bloc.
Qu'est-ce que page cache
et dentry cache
? Dans le paragraphe, cela signifie-t-il que les données ont été dupliquées parce que ramdisk
est traité comme un périphérique en mode bloc, de sorte que toutes les données sont mises en cache?
En comparaison, ramfs
:
Il y a quelques années, Linus Torvalds avait une bonne idée: que se passerait-il si le cache de Linux pourrait être monté comme un système de fichiers? Il suffit de garder les fichiers en cache et ne vous en débarrassez jamais tant qu'ils ne sont pas supprimés ou que le système ne redémarre pas? Linus a écrit un petit emballage autour du cache appelé "ramfs" et autres Les développeurs du noyau ont créé une version améliorée appelée "tmpfs" (qui peut écrire les données dans l'espace de swap, et limiter la taille d'un point de montage afin qu'il soit rempli avant d'utiliser toute la mémoire disponible). Initramfs est une instance de tmpfs.
Ces systèmes de fichiers basés sur la RAM s'agrandissent ou se réduisent automatiquement pour s'adapter au taille des données qu’ils contiennent. Ajouter des fichiers à un ramfs (ou étendre des fichiers Existants) alloue automatiquement plus de mémoire, et supprimer ou le fait de tronquer des fichiers libère cette mémoire. Il n'y a pas de duplication entre bloquer le périphérique et le cache, car il n'y a pas de périphérique de blocage. La copie dans le cache est la seule copie des données. Mieux encore, ce n'est pas nouveau code, mais une nouvelle application pour le code de mise en cache Linux existant, qui signifie qu’il n’a pratiquement pas de taille, qu’il est très simple et qu’il repose sur infrastructure extrêmement bien testée.
En résumé, ramfs
est simplement un fichier ouvert et chargé en mémoire, n'est-ce pas?
initrd
et ramfs
sont compressés au moment de la compilation, mais la différence est que initrd
est un périphérique bloc décompressé pour être monté par le noyau au démarrage, tandis que ramfs
est décompressé en mémoire par cpio. Ai-je raison? Ou ramfs
est-il un système de fichiers très minimal?
Enfin, jusqu’à ce jour, l’image initrd
est toujours présentée dans le dernier noyau. Cependant, cette initrd
est-elle réellement la ramfs
utilisée aujourd'hui et son nom n'a qu'un but historique?
Le sous-système de fichiers sous Linux a trois couches. Le système de fichiers virtuel (VFS), qui implémente l'interface des appels système et gère les points de montage croisés, ainsi que les autorisations et les contrôles par défaut. En dessous se trouvent les pilotes des systèmes de fichiers individuels et ceux-ci, à leur tour, se connectant aux pilotes des périphériques en mode bloc (disques, cartes mémoire, etc.; les interfaces réseau sont une exception).
L’interface entre VFS et le système de fichiers comprend plusieurs classes (c’est le C en clair, donc les structures contenant des pointeurs vers des fonctions, etc., mais c’est une interface orientée objet qui est conceptuelle). Les trois classes principales sont inode
, qui décrit tout objet (fichier ou répertoire) d'un système de fichiers, dentry
, qui décrit une entrée dans un répertoire et file
, qui décrit un fichier ouvert par un processus. Une fois monté, le pilote de système de fichiers crée inode
et dentry
pour sa racine et les autres sont créés à la demande lorsque le processus souhaite accéder à un fichier et expire par la suite. C'est un cache dentry et inode.
Oui, cela signifie que pour chaque fichier ouvert et pour tout répertoire jusqu'à la racine, il doit y avoir des structures inode
et dentry
allouées dans la mémoire du noyau qui le représente.
Sous Linux, chaque page de mémoire contenant des données utilisateur est représentée par la structure unifiée page
. Cela peut marquer la page comme anonyme (peut être permutée en espace de swap si disponible) ou l'associer à inode
sur un système de fichiers (peut être réécrit et relu à partir du système de fichiers) et peut faire partie d'un nombre illimité de mémoire. les cartes, c'est-à-dire visibles dans l'espace d'adressage d'un processus. La somme de toutes les pages actuellement chargées en mémoire est le cache de pages.
Les pages sont utilisées pour implémenter l’interface mmap et, bien que les appels système en lecture et en écriture puissent être implémentés par le système de fichiers par d’autres moyens, la majorité des interfaces utilise une fonction générique qui utilise également des pages. Il existe des fonctions génériques qui, lorsque la lecture du fichier est demandée, alloue des pages et appelle le système de fichiers pour les remplir, une par une. Pour les systèmes de fichiers basés sur des périphériques en mode bloc, il calcule simplement les adresses appropriées et délègue ce remplissage au pilote de périphérique en mode bloc.
Ramdev est un périphérique de bloc régulier. Cela permet de superposer n'importe quel système de fichiers dessus, mais cela est limité par l'interface de périphérique en mode bloc. Et cela n’a que des méthodes pour remplir une page allouée par l’appelant et la réécrire. C’est exactement ce qui est nécessaire pour les véritables périphériques en mode bloc, tels que les disques, les cartes mémoire, le stockage de masse USB, etc. Pour RAMDISK, cela signifie que les données sont stockées deux fois en mémoire, votre interlocuteur.
C'est l'ancienne façon de mettre en œuvre initrd
. Depuis des temps où initrd était rare et une occurrence exotique.
Tmpfs est différent. C'est un système de fichiers factice. Les méthodes fournies à VFS constituent le strict minimum pour le faire fonctionner (en tant que tel, il constitue une excellente documentation sur ce que devraient faire les méthodes inode, dentry et file). Les fichiers n'existent que s'il y a des inodes et des dentry correspondants dans le cache des inodes, créés lors de la création du fichier et n'expire jamais sauf si le fichier est supprimé. Les pages sont associées aux fichiers lorsque les données sont écrites et se comportent sinon comme des pages anonymes (les données peuvent être stockées pour être échangées, les structures page
restent utilisées tant que le fichier existe).
Cela signifie qu'il n'y a pas de copies supplémentaires des données en mémoire et que le processus est beaucoup plus simple et que, par conséquent, il est légèrement plus rapide. Il utilise simplement les structures de données, qui servent de cache pour tout autre système de fichiers, en tant que stockage principal.
C'est la nouvelle façon d'implémenter initrd
(initramfs
, mais l'image s'appelle toujours juste initrd
).
C’est aussi le moyen d’implémenter "posix shared memory" (ce qui signifie simplement que tmpfs est monté sur /dev/shm
et que les applications sont libres de créer des fichiers ici et de les utiliser; simples et efficaces) et récemment même /tmp
et /run
(ou /var/run
) ont souvent montés spécialement sur les ordinateurs portables pour éviter que les disques ne tournent ou éviter toute usure en cas de disque SSD.
Je pense que vous avez raison en tout.
La différence est facile à voir si vous suivez les étapes nécessaires au démarrage:
initrd
ramdev
est créé. Il s’agit d’un périphérique bloc basé sur la RAM, c’est-à-dire un disque dur simulé qui utilise la mémoire au lieu de disques physiques.initrd
est lu et décompressé dans le périphérique, comme si vous aviez zcat initrd | dd of=/dev/ram0
ou quelque chose de similaire. initrd
contient une image d'un système de fichiers. Vous pouvez donc maintenant monter le système de fichiers comme d'habitude: mount /dev/ram0 /root
. Naturellement, les systèmes de fichiers ont besoin d’un pilote. Ainsi, si vous utilisez ext2, le pilote ext2 doit être compilé dans le noyau.initramfs
tmpfs
est montée: mount -t tmpfs nodev /root
. Le tmpfs n'a pas besoin de pilote, il est toujours sur le noyau. Aucun périphérique requis, aucun pilote supplémentaire.initramfs
est décompressée directement dans ce nouveau système de fichiers: zcat initramfs | cpio -i
ou similaire.Et oui, il est toujours appelé initrd
dans de nombreux endroits, bien qu’il s’agisse d’un initramfs
, en particulier dans les chargeurs de démarrage, quant à eux, c’est juste un BLOB. La différence est faite par le système d'exploitation lors de son démarrage.
Pour ajouter une autre différence notable entre initrd
et initramfs
non mentionnée dans l'excellente réponse ci-dessus.
initrd
, le noyau transfère par défaut à l’espace utilisateur pid 0
à /sbin/init
pid 0
à /init
car cela pourrait devenir un piège (voir https://unix.stackexchange.com/a/147688/24394 )
Exemples minimaux exécutables de QEMU et explication de débutant
Dans cette réponse, je vais:
Espérons que ceux-ci serviront de base pour vérifier et comprendre les détails plus internes de la différence.
La configuration minimale est entièrement automatisée ici , et voici le correspondant pour commencer .
La configuration imprime les commandes QEMU au fur et à mesure de leur exécution et, comme expliqué dans ce référentiel, nous pouvons facilement produire les trois types de bottes de travail suivants:
le système de fichiers racine est dans un "disque dur" ext2:
qemu-system-x86_64 -kernel normal/bzImage -drive file=rootfs.ext2
le système de fichiers racine est dans initrd:
qemu-system-x86_64 -kernel normal/bzImage -initrd rootfs.cpio
-drive
n'est pas donné.
rootfs.cpio
contient les mêmes fichiers que rootfs.ext2
, à la différence qu’ils sont au format CPIO , qui est similaire à .tar
: il sérialise les répertoires sans les compresser.
le système de fichiers racine est dans initramfs:
qemu-system-x86_64 -kernel with_initramfs/bzImage
Ni -drive
ni -initrd
ne sont donnés.
with_initramfs/bzImage
est un noyau compilé avec des options identiques à normal/bzImage
, à une exception près: CONFIG_INITRAMFS_SOURCE=rootfs.cpio
pointant vers le même CPIO que dans l'exemple -initrd
.
En comparant les configurations, nous pouvons conclure les propriétés les plus fondamentales de chacune:
dans la configuration du disque dur, QEMU charge bzImage en mémoire.
Ce travail est normalement effectué par les chargeurs de démarrage/les microprogrammes dans du matériel réel tel que GRUB .
Le noyau Linux démarre, puis ses pilotes lisent le système de fichiers racine à partir du disque.
dans la configuration initrd, QEMU effectue quelques tâches supplémentaires du chargeur de démarrage en plus du chargement du noyau en mémoire:
rootfs.cpio
en mémoireCette fois-ci, le noyau utilise simplement le rootfs.cpio
directement de la mémoire, car aucun disque dur n’est présent.
Les écritures ne sont pas persistantes lors des redémarrages, car tout est en mémoire
dans la configuration initramfs, nous construisons le noyau un peu différemment: nous donnons également le rootfs.cpio
au système de construction du noyau.
Le système de construction du noyau sait alors comment coller l’image du noyau et le CPIO dans une seule image.
Par conséquent, tout ce que nous avons à faire est de passer le bzImage à QEMU. QEMU le charge dans l'image, comme pour les autres configurations, mais rien d'autre n'est requis: le CPIO est également chargé en mémoire puisqu'il est collé à l'image du noyau!