Différences entre les versions de « Initrd »

De BlaxWiki
Aller à la navigationAller à la recherche
 
Ligne 169 : Ligne 169 :


sudo nano /etc/initramfs-tools/modules
sudo nano /etc/initramfs-tools/modules
!! On peut utiliser lsinitrd pour voir les fichiers que contient un fichier initrd !!


Pour décompresser une image initrd :
Pour décompresser une image initrd :

Version actuelle datée du 9 février 2015 à 16:12

Initramfs[modifier]

Définition[modifier]

La version 2.6 du noyau linux a introduit le concept d'initramfs, une amélioration de l'initrd déjà présent dans les versions prédédentes. L'ancien Initrd qui existait dans les 
versions 2.4 est toujours supporté par les noyaux 2.6

Qu'est-ce qu'un initramfs ?
Dans le processus de démarrage d'un système Linux, tout commence par le chargement du noyau. Après s'être initialisé, celui-ci monte le système de fichiers racine (/), puis exécute 
le programme /sbin/init qui prend en charge la suite des opérations : initialisation du hostname, des interfaces réseau, lancement des divers services, etc...

Cela suppose toutefois qu'à l'issue de l'initialisation du noyau, le système de fichiers racine est disponible pour être monté. C'est généralement le cas, car ce système de fichiers 
se trouve la plupart du temps sur une partition du disque dur local, et le noyau possède toutes les informations pour le monter : pilote de disque dur, pilote IDE, pilote système de 
fichiers (ext2 par exemple). Mais il existe des situations où une préparation supplémentaire est nécessaire avant que le système de fichiers racine soit accessible :
    - / est un partage NFS, auquel cas il faut auparavant initialiser l'interface réseau
    - / se trouve sur un volume logique LVM, qui ne sera visible qu'après avoir exécuté un vgscan dans le cas d'un noyau complètement modulaire, les pilotes nécessaires pour monter / 
ne sont pas intégrés au noyau, il faut donc les insérer avant de procéder au montage

Dans tous ces cas de figure, on se trouve dans une situation où les outils nécessaires pour monter un système de fichiers se trouvent sur ce même système de fichiers. Impasse ? Non. 
C'est précisément à cela que sert l'initramfs !

L'initramfs est donc ceci : un mini système de fichiers, contenant tous les outils nécessaires au montage du véritable système racine. 
Un fichier initrd contient l'image compressée, au format gzip, d'un système de fichiers racine. Lors du démarrage, il est directement installé en mémoire dans un disque RAM par le 
chargeur grub. L'utilisation d'un fichier initrd est optionnel. Son intérêt principal est de charger les modules du noyau nécessaires durant les premiers stades du démarrage, 
principalement des modules SCSI, des modules de gestion de systèmes de fichiers (ext3, xfs, etc.) ou autres. Si le noyau possède statiquement ces modules, on peut se passer
d'un fichier initrd.

Configuration du noyeau[modifier]

Voici les options qui doivent impérativement être sélectionnées lors de la configuration du noyau pour que celui-ci puisse faire usage de l'initramfs :

Section Device drivers/Block devices:
<*>    RAM disk support
(4096) Default RAM disk size (kbytes)
[*]    Initial RAM disk (initrd) support
Section File systems/Pseudo filesystems:
[*] /proc file system support
[*] Virtual memory file system support (former shm fs)

Création automatique de initramfs[modifier]

* Pour créer une image initrd,il suffit de donner en paramètre le chemin et le nom du fichier initrd ainsi que l'emplacement des modules du noyau /lib/modules/version_du_noyau :

dracut -f initramfs-2.6.32-71.el6.x86_64.img 2.6.32-71.el6.x86_64 (ancien kernel : mkinitramfs -o /boot/initrd.img-$(uname -r) /lib/modules/$(uname -r))

* Charger tous les modules
Dans les kernel récents, utiliser dracut -N --force : Le "-N" charge tous les modules, et pas seulement ceux utiles pour le serveur en question

* Pour mettre à jour un initrd :

sudo update-initramfs -u -v

Pour rajouter des modules dans un initrd, inscrire le nom du module dans /etc/initramfs-tools/modules puis mettre à jour l'initrd :

sudo nano /etc/initramfs-tools/modules

Creation manuelle de initramfs[modifier]

Répertoire de travail

Commençons par créer un répertoire dans lequel nous construirons l'arborescence de notre initramfs. Celle-ci comprendra les répertoires habituels, ainsi que les devices 
indispensables dans /dev.

mkdir rootfs
cd rootfs
mkdir bin
mkdir lib
mkdir etc
mkdir proc
mkdir sys
ln -s bin sbin
mkdir dev

cd dev
mknod console c 5 1
mknod null c 1 3
mknod systty c 4 0
mknod tty1 c 4 1
mknod tty2 c 4 2
mknod tty3 c 4 3
mknod tty4 c 4 4
mknod ram b 1 1
  • Le script init

Une fois l'initramfs monté en tant que système de fichiers racine, le noyau exécute le programme init situé à la racine du système de fichiers. Dans notre exemple, il s'agira d'un script shell chargé de préparer le véritable /, situé sur un volume LVM.

#!/bin/sh
echo Loading Device Mapper
insmod /lib/dm-mod.ko

echo Mounting /proc
mount -n -t proc proc /proc

echo Mounting /sys
mount -n -t sysfs sysfs /sys

echo Starting udev
udevstart

echo Unmounting /sys
umount /sys

echo Detecting LVM volumes
vgscan
echo Activating LVM volumes
vgchange -a y

ROOT=$(cat /proc/cmdline | tr ' ' 'n' | grep ^root= | cut -d= -f2)
echo Command line root is $ROOT

echo Mounting real root filesystem
mount -n -o ro $ROOT /mnt

echo Unmounting /proc
umount /proc

echo Running init
exec bin/run-init /mnt /sbin/init $*
  • Explication
Dans un premier temps, le script charge les modules dont il a besoin. Si tous les pilotes nécessaires ont été compilés dans le noyau, cette étape est naturellement inutile.
Puis il monte les pseudo systèmes de fichiers /proc et /sys, qui seront nécessaires au fonctionnement des programmes lancés par la suite.
L'appel à udevstart permet de remplir /dev avec les devices connus par le noyau. Une alternative consisterait à remplir statiquement /dev, mais cela oblige à être exhaustif et à 
inclure nombre de devices parfaitement inutiles. Dans le cas de LVM, il deviendrait de plus impossible de changer le nom du volume racine, car l'initramfs ne contiendrait pas le 
device correspondant. L'un dans l'autre, l'approche udev est à la fois plus souple et plus élégante !
vgscan et vgchange permettent de détecter les volumes LVM et de les activer. Les devices correspondants sont automatiquement ajoutés à /dev.

L'étape suivante consiste à rechercher dans les paramètres passés au noyau, un paramètre de la forme root=device qui donnera le nom du device sur lequel se trouve le véritable système 
de fichiers racine. On monte alors ce device sur /mnt.

Le script exécute ensuite le programme run-init, qui va remplacer l'initramfs par le système de fichiers monté sur /mnt en tant que racine, libérer les ressources utilisées par 
l'initramfs, et appeler le véritable /sbin/init avec les paramètres qu'init a reçu du bootloader.

Notons au passage les programmes auxquels fait appel init, et qu'il faudra inclure dans l'initramfs avec leurs dépendances :
    Un shell !
    echo, insmod, mount, umount, cat, grep, cut, tr
    udevstart
    vgscan, vgchange
    run-init

Initrd[modifier]

Pour créer une image initrd,il suffit de donner en paramètre le chemin et le nom du fichier initrd à produire ainsi que l'emplacement des modules du noyau
/lib/modules/version_du_noyau :

mkinitramfs -o /boot/initrd.img-$(uname -r) /lib/modules/$(uname -r)
ou plus simplement
mkinitramfs -o /boot/initrd.img-$(uname -r)


Dans les kernel récents, utiliser dracut -N --force : Le "-N" charge tous les modules, et pas seulement ceux utiles pour le serveur en question

Pour mettre à jour un initrd :

sudo update-initramfs -u -v

Pour rajouter des modules dans un initrd, inscrire le nom du module dans /etc/initramfs-tools/modules puis mettre à jour l'initrd :

sudo nano /etc/initramfs-tools/modules

!! On peut utiliser lsinitrd pour voir les fichiers que contient un fichier initrd !!

Pour décompresser une image initrd :

cp /boot/initrd.img /tmp
cd /tmp
gunzip -c initrd.img > initrd
cat initrd | cpio -idv
rm initrd
  • Génération & modification manuel de initrd.img
* Nouvelle méthode (kernel > 3.x)
Il faut utiliser lsinitrd  pour voir ce que contient le fichier .img

# Generer un initrd
mkinitrd /boot/initrd.img 2.6.xxxx
Options pour du ajouter un module (en plus de ceux dans modprobe.conf
mkinitrd --preload=raid1 /boot/initrd.img 2.6.

# Decompresser un initrd.img :
gzip -dc initrd.img | cpio -ivd

# Recompresser un initrd
Dans le rep ou est décompressé l initrd :
find ./ | cpio -H newc -o > ../initrd.cpio
gzip initrd.cpio
mv initrd.cpio.gz initrd.cpio.img

Pour grub :

# Mettre /boot si il n y a pas de partition pour /boot, sinon on met juste /
title           Debian GNU/Linux, kernel 2.6.29
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.29 root=/dev/hda1 ro quiet
initrd          /boot/initrd.img-2.6.29