web-dev-qa-db-fra.com

La différence entre initrd et initramfs?

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? 

48
Amumu

Cache de dentry (et d'inode)

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.

Cache de page

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 (disque mémoire)

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

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.

42
Jan Hudec

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

  • Un périphérique de bloc 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.
  • Le fichier 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. 
  • La 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.
  • Terminé!

initramfs

  • Une 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.
  • La initramfs est décompressée directement dans ce nouveau système de fichiers: zcat initramfs | cpio -i ou similaire.
  • Terminé!

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.

52
rodrigo

Pour ajouter une autre différence notable entre initrd et initramfs non mentionnée dans l'excellente réponse ci-dessus.

  • Avec initrd, le noyau transfère par défaut à l’espace utilisateur pid 0 à /sbin/init
  • Initramfs plus récent change cependant les choses et exécute pid 0 à /init

car cela pourrait devenir un piège (voir https://unix.stackexchange.com/a/147688/24394 )

0
humanityANDpeace

Exemples minimaux exécutables de QEMU et explication de débutant

Dans cette réponse, je vais:

  • fournir un exemple minimal runnable Buildroot + QEMU pour vous permettre de tester les choses
  • expliquer la différence la plus fondamentale entre les deux tout débutants qui sont probablement googler cette

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:

  1. le système de fichiers racine est dans un "disque dur" ext2:

    qemu-system-x86_64 -kernel normal/bzImage -drive file=rootfs.ext2
    
  2. 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.

  3. 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:

  1. 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.

  2. 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:

    Cette 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

  3. 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!