Initrd
| Fiche express | |
|---|---|
| Domaine | Ramdisk initial de boot (montage de la racine) |
| Fichier | /boot/initrd-<version>.img
|
| Outil (RHEL5/6) | mkinitrd
|
| Outil (RHEL7+) | dracut
|
| Contexte | RHEL/CentOS 5 et 6 — remplacé par dracut sur RHEL7+ |
| Voir aussi | Kernel · Init |
initrd (initial ramdisk) est une image de système de fichiers temporaire, chargée en
mémoire par le chargeur de démarrage (GRUB) en même temps que le noyau. Elle embarque les
pilotes et modules nécessaires pour monter la vraie racine (/) — typiquement les
pilotes de contrôleur disque (RAID, SCSI) ou de carte réseau pour un boot PXE — avant que le
noyau ne bascule dessus. Sur RHEL/CentOS 5 et 6, ces images sont générées et modifiées avec
mkinitrd ; sur RHEL7 et les distributions récentes, cet outil est remplacé par
dracut (voir plus bas), mais le principe reste le même.
Inspecter un initrd existant
Un initrd RHEL5/6 est une archive cpio compressée en gzip ; on peut lister son contenu sans le modifier :
zcat /boot/initrd-$(uname -r).img | cpio -itv
Les modules disponibles pour le noyau en cours se trouvent quant à eux dans
/lib/modules/$(uname -r)/kernel/.
Ajouter un module avec mkinitrd
mkinitrd permet de reconstruire un initrd en y intégrant un module supplémentaire,
sans avoir à démonter/remonter l'archive à la main. Deux options :
--with=<module>: ajoute le module à l'image, chargé si besoin (cas le
plus courant, ex. un pilote RAID).
--preload=<module>: ajoute le module et force son chargement au
démarrage du système.
cd /boot
# Ajouter le module raid1 (⚠️ toujours écrire vers un nouveau fichier, ne jamais écraser
# l'initrd en place — un système qui ne boote plus est bien plus difficile à corriger)
mkinitrd --with=raid1 initrd-raid1-$(uname -r).img $(uname -r)
# Forcer le chargement d'un module au démarrage (ex. carte RAID matérielle)
mkinitrd --preload=megaraid initrd-megaraid-$(uname -r).img $(uname -r)
Il reste ensuite à déclarer le nouvel initrd dans GRUB (/boot/grub/grub.conf), en
dupliquant le bloc de l'entrée de boot existante :
title Red Hat Enterprise Linux ES (2.6.9-42.EL)
root (hd0,0)
kernel /vmlinuz-2.6.9-42.EL ro root=/dev/rootvg/lvroot
initrd /initrd-raid1-2.6.9-42.EL.img
Puis redémarrer sur cette entrée pour valider avant de la rendre permanente.
Ajouter un module manuellement
Utile quand mkinitrd n'est pas disponible (ex. modification d'un initrd
d'installation, comme celui du pxeboot d'un CD/DVD Red Hat), ou pour comprendre
la structure interne de l'archive. La procédure consiste à :
- extraire le contenu de l'initrd ;
- ajouter le pilote (fichier
.koou.o) ; - déclarer le nouveau matériel dans
module-infoetpcitable; - reconstruire l'archive.
Extraire l'initrd
# Récupérer initrd.img sur le média d'installation (ex. images/pxeboot/initrd.img du CD/DVD)
mv initrd.img initrd.img.gz
gunzip initrd.img.gz
# Monter le filesystem
mkdir mount-initrd
mount -o loop initrd.img mount-initrd
Les modules sont eux-mêmes dans une seconde archive imbriquée,
mount-initrd/modules/modules.cgz, qu'il faut extraire à son tour :
cp mount-initrd/modules/modules.cgz .
mv modules.cgz modules.gz
gunzip modules.gz
cpio -idv < modules
Ajouter le pilote
# Copier le .ko / .o dans le répertoire décompressé (adapter le chemin à l'arch/version)
cp bnx2.o ./2.4.21-37.ELBOOT/i386/
Déclarer le module dans module-info, par exemple pour une carte Broadcom
NetXtreme II :
# bnx2
eth
"Broadcom NetXtreme II Gigabit Ethernet Driver"
Puis déclarer le(s) identifiant(s) PCI du matériel dans pcitable (à récupérer
auprès du constructeur, ou par comparaison avec un pcitable existant via
grep bnx2 /usr/share/hwdata/pcitable) :
0x14e4 0x164a "bnx2" "Broadcom Corporation|NetXtreme II BCM5706 Gigabit Ethernet"
0x14e4 0x164c "bnx2" "Broadcom Corporation|NetXtreme II BCM5708 Gigabit Ethernet"
0x14e4 0x16aa "bnx2" "Broadcom Corporation|NetXtreme II BCM5706S Gigabit Ethernet"
0x14e4 0x16ac "bnx2" "Broadcom Corporation|NetXtreme II BCM5708S Gigabit Ethernet"
Reconstruire l'archive
# Reconstruire modules.cgz
find ./2.4.21-37.ELBOOT | cpio -ocv > modules
gzip -9 modules
mv modules.gz mount-initrd/modules/modules.cgz
# Démonter et recompresser l'initrd
umount mount-initrd
gzip -9 initrd.img
mv initrd.img.gz initrd.img
Sur les systèmes récents : dracut
Sur RHEL7 et les distributions récentes, mkinitrd est remplacé par
dracut, qui régénère l'intégralité de l'initramfs (plutôt que d'y injecter un
module à la main) :
# Régénérer l'initramfs du noyau en cours, avec un module supplémentaire
dracut --force --add-drivers raid1 /boot/initramfs-$(uname -r).img $(uname -r)
# Lister le contenu d'un initramfs existant (équivalent de la commande cpio ci-dessus)
lsinitrd /boot/initramfs-$(uname -r).img
⚠️ Comme pour mkinitrd, éviter d'écraser l'image en place avant d'avoir validé le
démarrage sur un nouveau fichier déclaré en parallèle dans GRUB.