Pourquoi ai-je besoin d'initramfs?

17

J'ai découvert que si je choisis jffsou sdcomme système de fichiers (et non initramfs), la taille du noyau sera très petite (1,4 Mo par rapport à 3,4 Mo initramfs). Cela signifie que cela initramfsprend beaucoup de place. Donc, si je le peux, je le supprimerais complètement et aurais donc un très petit noyau, ce que je veux.

La question fondamentale qui me vient à l'esprit est: pourquoi ai-je besoin initramfs? Impossible de démarrer un noyau Linux sans avoir de système de fichiers initial?

Mon application finale ne fera que le calcul et la communication - pas de stockage du tout. Un système d'exploitation sans système de fichiers a donc un sens - du moins pour mon application.

gpuguy
la source
2
Vous ne pouvez pas vous passer d'initramfs. Il est possible de se passer du fichier initramfs supplémentaire, mais peu importe ce que vous faites, le noyau inclut son propre fichier vide ou non. Je ne comprends donc pas votre question - de quelle distribution parlez-vous? Comment construisez-vous votre noyau? Pouvez-vous fournir le fichier .config du noyau? Ce sont très importants. Je soupçonne que votre distribution compile ses initramfs directement dans le noyau - et remplit donc les initramfs autrement vides qu'elle contient - mais je ne peux pas le savoir sur la base des informations que vous avez fournies.
mikeserv
2
@mikeserv, évidemment un initramfs intégré mais vide / inutilisé ne compte pas.
psusi
Eh bien, @psusi, les documents du noyau ne sont pas d'accord. Et je suis si catégorique à ce sujet parce qu'il n'y a pas besoin de mystère - c'est juste /root- c'est tout. La seule chose qu'il fait différemment est switch_rootmais même cela, à condition que des précautions appropriées soient prises avec certains modules du noyau chargés, peut être fait à tout moment. Initramfs n'est rien d'autre qu'une image disque - débordante ou non, elle est là. Et vous n'en êtes jamais sans - c'est votre racine après tout. Cela ne devrait pas être un mystère, c'est ce que je pense, et je n'aime pas toute la confusion inutile qui l'entoure.
mikeserv
2
@mikeserv, non, / root est le répertoire personnel de l'utilisateur root. Le rootfs est /, qui a alors la vraie racine montée par-dessus. Vous discutez simplement de la sémantique. Pour les besoins de cette discussion, ne pas avoir d'initramfs signifie ne pas avoir de fichier sur le disque que votre chargeur de démarrage doit charger et passer au noyau.
psusi
C'est vrai, j'ai seulement utilisé / root pour plus de clarté, mais je vais vous donner celui-là. Mais non, ce ne sont pas des sémantiques, ce sont les mécanismes fondamentaux de votre noyau Linux. Ce sont des choses de base. Essayons juste de les faire bien.
mikeserv

Réponses:

12

L'augmentation de la taille d'avoir un initramfs n'est pas due au pilote ramfs (il n'est que de quelques ko, et de toute façon nécessaire pour d'autres choses) mais aux initramfs lui-même. Les initramfs contiennent des programmes qui sont nécessaires pour assembler et monter le vrai système de fichiers racine.

Initramfs facilite /le démarrage du système et, dans certains cas, il est possible (par exemple crypté ). Il est fortement recommandé de le conserver sur du matériel de style PC avec beaucoup de périphériques enfichables à chaud. D'un autre côté, il est très logique de démarrer un périphérique intégré sans initramfs, avec un noyau qui prend simplement en charge la configuration matérielle particulière pour laquelle il est conçu.

Le noyau doit bien sûr démarrer sur un système de fichiers: il doit y avoir un moyen de charger n'importe quelle application que vous souhaitez exécuter. Si vous ne voulez rien faire, vous pouvez tout aussi bien garder la machine hors tension.

Si vous ne voulez pas utiliser d'initramfs, dites simplement à votre chargeur de démarrage de ne pas en passer un. N'en incluez pas non plus dans la sortie de la construction du noyau, bien sûr - comment cela se produit si tout dépend de l'architecture et du chargeur de démarrage: par exemple, vmlinuxet bzImagen'incluez pas les initramfs (ce sont respectivement le noyau brut et le noyau compressé ), mais uImage(pour U-Boot) contient à la fois le noyau et les initramfs s'il y en a un.

(Techniquement, comme le note mikeserv , il y a toujours un initramfs - mais par défaut, c'est une archive vide de 134 octets. Ce que vous voyez et que vous voulez vous débarrasser, c'est un "vrai" initramfs non vide créé par votre processus de construction et contenant des outils qui sont ensuite utilisés pour monter le système de fichiers racine.)

Attention, un initramfs peut être un moyen raisonnable de créer un système à application unique sans données persistantes: mettez toute votre application dans les initramfs, démarrez-la et conservez-la. Cela facilite l'organisation de votre stockage persistant ou de votre image de démarrage (tout ce dont vous avez besoin est le noyau et les initramfs, qui peuvent être regroupés). Il y a cependant des inconvénients à cette approche: toutes les données dans les initramfs seront stockées en RAM de façon permanente, et vous ne pouvez pas facilement modifier les fichiers dans l'image de démarrage, vous devez reconstruire l'archive.

Gilles 'SO- arrête d'être méchant'
la source
Si vous utilisez un noyau Linux 2.6 ou plus récent, vous avez initramfs. Que vous utilisiez ou non une image initramfs secondaire, comme c'est la coutume, c'est une autre question, mais initramfs n'est pas facultatif.
mikeserv
2
@mikeserv Vous en avez un, oui. Mais un initramfs vide est des arachides. Il n'est pas nécessaire de l' utiliser (ce qui nécessite qu'il contienne suffisamment de programmes pour monter la vraie racine, ce qui augmente la taille de manière non négligeable dans un système embarqué typique).
Gilles 'SO- arrête d'être méchant'
Arachides obligatoires de toute façon. Et je ne sais pas quand j'ai dit le contraire! Le demandeur demandait des informations sur la façon de le supprimer en tant que système de fichiers - ce qui n'est pas possible.
mikeserv
Et oui, il doit être utilisé - sans initramfs, il n'y a pas de racine. Déjà.
mikeserv
8

Depuis LFS :

Le seul but d'un initramfs est de monter le système de fichiers racine. Les initramfs sont un ensemble complet de répertoires que vous trouverez sur un système de fichiers racine normal. Il est regroupé dans une seule archive cpio et compressé avec l'un des nombreux algorithmes de compression.

...

Il n'y a que quatre raisons principales pour avoir un initramfs dans l'environnement LFS: charger les rootfs à partir d'un réseau, le charger à partir d'un volume logique LVM, avoir un rootfs chiffré où un mot de passe est requis, ou pour la commodité de spécifier les rootfs en tant que ÉTIQUETTE ou UUID. Toute autre chose signifie généralement que le noyau n'a pas été configuré correctement.

...

Pour la plupart des distributions, les modules du noyau sont la principale raison d'avoir un initramfs. Dans une distribution générale, il existe de nombreuses inconnues telles que les types de système de fichiers et les dispositions de disque. D'une certaine manière, c'est l'opposé de LFS où les capacités et la disposition du système sont connues et un noyau personnalisé est normalement construit. Dans cette situation, un initramfs est rarement nécessaire.

Une autre source www.kernel.org

En plus de cela, il y a beaucoup de systèmes Linux qui aiment les routeurs qui n'utilisent pas initramfs.


la source
1

Vous avez besoin d'un initramfs pour les configurations plus complexes, telles que le démarrage réseau, ou lvm ou raid, car elles nécessitent certains utilitaires en mode utilisateur pour configurer l'accès aux root fs. Pour une partition simple et conventionnelle sur un disque, tant que les pilotes de disque sont intégrés dans le noyau et que vous spécifiez l'argument racine par chemin de périphérique plutôt que par UUID, vous pouvez vous passer d'un initramfs. Bien sûr, le chemin du périphérique est susceptible de changer, en fonction des périphériques plug-and-play (c'est-à-dire usb) que vous avez connectés, ou même simplement des variations de synchronisation aléatoires, c'est pourquoi presque tout le monde utilise des uuids et un initramfs pour plus de fiabilité.

psusi
la source
C'est également incorrect.
mikeserv
6
@mikeserv, votre commentaire est inutile. Si vous allez prétendre cela, vous devez expliquer pourquoi.
psusi
J'ai fait, ou plutôt, la documentation du noyau qui compose 99% de ma réponse.
mikeserv
@mikeserv, c'est correct. J'utilise Gentoo linux depuis des années sans initramfs.
Tim
1

Ceci est une vieille question mais ne semble toujours pas avoir de réponse acceptée, donc je vais jeter cela là-bas (je ne suis pas un expert ici, j'essaie de comprendre cela par moi-même.)

De https://www.kernel.org/doc/Documentation/early-userspace/README (tout en bas qui indique qu'il n'a pas été mis à jour depuis 2004.)

Le noyau a actuellement 3 façons de monter le système de fichiers racine:

a) tous les pilotes de périphérique et de système de fichiers requis compilés dans le noyau, pas d'initrd. init / main.c: init () appellera prepare_namespace () pour monter le système de fichiers racine final, basé sur l'option root = et optionnel init = pour exécuter un autre binaire init que celui indiqué à la fin de init / main.c: init ().

b) certains pilotes de périphériques et de systèmes de fichiers construits en tant que modules et stockés dans un initrd. L'initrd doit contenir un binaire '/ linuxrc' qui est censé charger ces modules de pilotes. Il est également possible de monter le système de fichiers racine final via linuxrc et d'utiliser le syscall pivot_root. L'initrd est monté et exécuté via prepare_namespace ().

c) en utilisant initramfs. L'appel à prepare_namespace () doit être ignoré. Cela signifie qu'un binaire doit faire tout le travail. Ledit binaire peut être stocké dans initramfs soit en modifiant usr / gen_init_cpio.c ou via le nouveau format initrd, une archive cpio. Il doit être appelé "/ init". Ce binaire est responsable de faire tout ce que prepare_namespace () ferait.

Pour conserver la compatibilité descendante, le binaire / init ne s'exécutera que s'il provient d'une archive cpio initramfs. Si ce n'est pas le cas, init / main.c: init () exécutera prepare_namespace () pour monter la racine finale et exécuter l'un des binaires init prédéfinis.

Pour ce que ça vaut, je crois que les appareils / distributions tels que Raspberry Pi, etc. n'utilisent pas d'initramfs; dans certains cas, le noyau est sur la partition racine (monté par le chargeur de démarrage qui a les modules fs requis.) Dans d'autres cas où le noyau est par exemple sur une /bootpartition, les initramfs sur la même partition sont accessibles directement avant de monter les rootfs comme d'autres ont déclaré.

Dans certains cas, les initramfs peuvent être intégrés dans le même fichier que le noyau mais ce n'est pas toujours le cas. (a) semble indiquer assez clairement que dans certains cas, initramfs n'est pas nécessaire.

thom_nic
la source
0

Je trouve l' explication suivante plus claire,

initramfsest un système de fichiers racine intégré au noyau et chargé à un stade précoce du processus de démarrage. C'est le successeur d'initrd. Il fournit un espace utilisateur précoce qui peut faire des choses que le noyau ne peut pas faire facilement tout seul pendant le processus de démarrage.

L'utilisation d'initramfs est facultative. Par défaut, le noyau initialise le matériel à l'aide de pilotes intégrés, monte la partition racine spécifiée, charge le système init de la distribution Linux installée. Le système init charge ensuite des modules supplémentaires et démarre les services jusqu'à ce qu'il vous permette éventuellement de vous connecter. Il s'agit d'un bon comportement par défaut et suffisant pour de nombreux utilisateurs. initramfs est destiné aux utilisateurs ayant des exigences avancées; pour les utilisateurs qui doivent faire les choses le plus tôt possible, avant même le montage de la partition racine.

Voici quelques exemples de ce que vous pouvez faire avec initramfs:

  • Montez la partition racine (pour les partitions chiffrées, logiques et autrement spéciales);
  • Fournir une coque de sauvetage minimaliste (en cas de problème);
  • Personnalisez le processus de démarrage (par exemple, imprimez un message de bienvenue, un démarrage, etc.);
  • Charger des modules (par exemple des pilotes tiers);
  • Tout ce que le noyau ne peut pas faire (tant que vous pouvez le faire dans l'espace utilisateur, par exemple en exécutant des commandes). Si vous n'avez pas d'exigences avancées, vous n'avez pas besoin d'initramfs.
Soufiyan Ghori
la source
-1

Peu importe ce que vous faites, vous l'avez initramfs. Il est impossible de s'en passer - c'est le seul système de fichiers qui vous est imposé. De kernel.org :

Qu'est-ce que rootfs?

Rootfsest un cas particulier de ramfs(ou tmpfs, si cela est permis), qui est toujours présent dans les systèmes 2.6. Vous ne pouvez pas démonterrootfs pour à peu près la même raison que vous ne pouvez pas tuer le processus d'initialisation; plutôt que d'avoir du code spécial pour rechercher et gérer une liste vide, il est plus petit et plus simple pour le noyau de s'assurer que certaines listes ne peuvent pas devenir vides.

La plupart des systèmes montent simplement un autre système de fichiers rootfset l'ignorent. La quantité d'espace qu'une instance vide de ramfs occupe est minuscule.

Si * CONFIG_TMPFS * est activé, rootfsutilisera à la tmpfsplace de ramfspar défaut. Pour forcer ramfs, ajoutez "rootfstype=ramfs"à la ligne de commande du noyau.

Qu'est-ce que initramfs?

Tous les noyaux Linux 2.6 contiennent une archive au"cpio"formatgzippé, qui est extraite au rootfsdémarrage du noyau. Après extraction, le noyau vérifie pour voir sirootfscontient un fichier"init" , et s'il l'exécute comme PID 1. Si trouvé, ceinitprocessus est responsable de mettre le système le reste du chemin, y comprislocalisation etmontage du dispositif réel racine ( si seulement). Sirootfsne contient pas deinitprogramme après que l'cpioarchiveintégrée yest extraite, le noyau passera à l'ancien code pour localiser et monter une partition racine, puis exécutera une variante/sbin/initde celle-ci.

Tout cela diffère de l'ancien initrd à plusieurs égards:

  • L'ancien initrd était toujours un fichier séparé, tandis que l'archive initramfs est liée à l'image du noyau linux. (Le répertoire linux - * / usr est consacré à la génération de cette archive lors de la construction.)

  • L'ancien fichier initrd était une image du système de fichiers gzippé (dans certains formats de fichier, comme ext2, qui nécessitait un pilote intégré au noyau), tandis que la nouvelle archive initramfs est une archive cpio gzippée (comme tar plus simple, voir cpio (1) et Documentation / early-userspace / buffer-format.txt). Le code d'extraction cpio du noyau n'est pas seulement extrêmement petit, c'est aussi du texte et des données __init qui peuvent être supprimés pendant le processus de démarrage.

  • Le programme exécuté par l'ancien initrd (qui s'appelait / initrd, pas / init) a fait une configuration puis est retourné au noyau, tandis que le programme init de initramfs ne devrait pas retourner au noyau. (Si / init a besoin de transférer le contrôle, il peut sur-monter / avec un nouveau périphérique racine et exécuter un autre programme init. Voir l'utilitaire switch_root ci-dessous.)

  • Lors de la commutation d'un autre périphérique racine, initrd pivot_root puis démontait le ramdisk. Mais initramfs est rootfs: vous ne pouvez ni pivot_root rootfs, ni le démonter. Au lieu de cela, supprimez tout de rootfs pour libérer de l'espace (find -xdev / -exec rm '{}' ';'), surmontez rootfs avec la nouvelle racine (cd / newmount; mount --move. /; Chroot.), attachez stdin / stdout / stderr au nouveau / dev / console, et exécutez le nouveau init.

Comme il s'agit d'un processus remarquablement persévérant (et implique la suppression de commandes avant de pouvoir les exécuter), le package klibc a introduit un programme d'aide (utils / run_init.c) pour faire tout cela pour vous. La plupart des autres packages (tels que busybox) ont nommé cette commande "switch_root".

Remplissage des initramfs:

Le processus de construction du noyau 2.6 crée toujours une archive initramfs au format cpio compressé et la relie au binaire du noyau résultant. Par défaut, cette archive est vide (consommant 134 octets sur x86).

L'option de configuration CONFIG_INITRAMFS_SOURCE (dans General Setup dans menuconfig, et vivant dans usr / Kconfig) peut être utilisée pour spécifier une source pour l'archive initramfs, qui sera automatiquement incorporée dans le binaire résultant. Cette option peut pointer vers une archive cpio gzippée existante, un répertoire contenant des fichiers à archiver ou une spécification de fichier texte telle que l'exemple suivant:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Exécutez "usr / gen_init_cpio" (après la construction du noyau) pour obtenir un message d'utilisation documentant le format de fichier ci-dessus.

Un avantage du fichier de configuration est que l'accès root n'est pas requis pour définir les autorisations ou créer des nœuds de périphérique dans la nouvelle archive. (Notez que ces deux exemples d'entrées de "fichier" s'attendent à trouver des fichiers nommés "init.sh" et "busybox" dans un répertoire appelé "initramfs", sous le répertoire linux-2.6. *. Voir Documentation / early-userspace / README pour plus de détails.)

Le noyau ne dépend pas des outils cpio externes. Si vous spécifiez un répertoire au lieu d'un fichier de configuration, l'infrastructure de construction du noyau crée un fichier de configuration à partir de ce répertoire (usr / Makefile appelle scripts / gen_initramfs_list.sh) et procède à l'empaquetage de ce répertoire à l'aide du fichier de configuration (en le nourrissant dans usr / gen_init_cpio, qui est créé à partir de usr / gen_init_cpio.c). Le code de création de cpio au moment de la construction du noyau est entièrement autonome, et l'extracteur au démarrage du noyau est également (évidemment) autonome.

mikeserv
la source
1
Vous pouvez démarrer sans initramfs. Votre réponse expose les mérites des initramfs, mais cela ne s'applique pas aux systèmes embarqués typiques, et même sur les postes de travail ou les serveurs où un initramfs est recommandé, il n'est pas obligatoire.
Gilles 'SO- arrête d'être méchant'
@ Gilles - non tu ne peux pas. Peu importe ce que vous faites, vous avez des initramfs. Il est compilé dans le noyau - en ce moment, votre noyau, mon noyau, tous nos noyaux. Lisez les documents du noyau - mon article entier était un copier-coller. Vous vous trompez. Comment contester la documentation officielle?
mikeserv
1
Je ne conteste pas la documentation officielle, je conteste les conclusions que vous en tirez. Vous lisez de la documentation qui explique comment utiliser un initramfs. Nulle part il n'indique que les initramfs doivent être utilisés.
Gilles 'SO- arrête d'être méchant'
@Gilles Si cela ne suffit pas: "Le processus de construction du noyau 2.6 crée toujours une archive initramfs au format cpio compressé et la relie au binaire du noyau résultant. Par défaut, cette archive est vide (consommant 134 octets sur x86) .... " Je peux faire mieux. Ce qui précède était une recherche sur le Web de 2 ou 3 minutes.
mikeserv
3
J'ai lu la documentation. Je fais ça pour gagner ma vie. Ce n'est pas une question d'opinion. Il y a toujours un initramfs, mais il n'est pas nécessairement utilisé pour le démarrage. Je ne peux pas trouver une explication décente de la structure du noyau pour ce cas, probablement parce que c'est le cas classique qui ne mérite pas d'explication. La logique principale est in do_mounts.c- spécifiquement prepare_namespace, dans laquelle saved_root_namevient rempli l' root=argument de ligne de commande.
Gilles 'SO- arrête d'être méchant'