Chapitre 3. Initialisation du système

Table des matières

3.1. Aperçu du processus d’amorçage du système
3.1.1. Étage 1 : UEFI
3.1.2. Étage 2 : le chargeur initial
3.1.3. Étage 3 : le système mini-Debian
3.1.4. Étage 4 : le système Debian normal
3.2. Systemd
3.2.1. Initialisation avec Systemd
3.2.2. Connexion avec Systemd
3.3. Messages du noyau
3.4. Messages du système
3.5. Gestion du système
3.6. Autres moniteurs du système
3.7. Configuration du système
3.7.1. Nom de machine (« hostname »)
3.7.2. Le système de fichiers
3.7.3. Initialisation de l’interface réseau
3.7.4. Initialisation du système d’infonuagique
3.7.5. Exemple de personnalisation pour ajuster le service sshd
3.8. Le système udev
3.9. Initialisation des modules du noyau

En tant qu’administrateur du système, il est sage que vous sachiez en gros comment le système Debian est démarré et configuré. Bien que les détails exacts figurent dans les fichiers sources des paquets installés et dans leurs documentations, c’est un peu pénible pour la plupart d’entre-nous.

Voici un aperçu succinct des points clé de l'initialisation du système Debian. Comme le système Debian évolue constamment, vous devriez vous référer à la dernière documentation.

Le système informatique subit plusieurs phases de processus d’amorçage (« boot strap process ») depuis l’événement de mise sous tension jusqu’à ce qu’il offre à l’utilisateur un système d’exploitation (OS) pleinement fonctionnel.

Pour des raison de simplicité, je limiterai la discussion à une plateforme PC typique avec l’installation par défaut.

Le processus d’amorçage typique est comme une fusée à quatre étages. Chaque étage de la fusée passe le contrôle du système à l’étage suivant.

Bien entendu, elles peuvent être configurées de manière différente. Par exemple, si vous avez compilé votre propre noyau, vous pouvez sautez l’étape avec le système mini-Debian. Ne supposez donc pas que c’est le cas sur votre système avant de l’avoir vérifié vous-même.

L’ interface micrologicielle extensible unifiée UEFI définit un gestionnaire de démarrage dans le cadre de la spécification UEFI. Lorsqu'un ordinateur est démarré, le gestionnaire de démarrage est le 1er étage du processus d’amorçage qui vérifie la configuration de démarrage et, en fonction de ses réglages, exécute alors le chargeur de démarrage ou le noyau du système d'exploitation spécifié (généralement le chargeur de démarrage). La configuration de démarrage est définie par les variables stockées dans la mémoire RAM non volatile, y compris les variables qui indiquent le chemin des systèmes de fichiers vers les chargeurs de démarrage ou les noyaux de système d’exploitation.

Une partition système EFI (ESP) est une partition de périphérique de stockage de données qui est utilisée dans les ordinateurs adhérant à la spécification UEFI. Accédée par le micrologiciel UEFI quand un ordinateur est démarré, elle stocke les applications UEFI et les fichiers dont ces applications ont besoin pour fonctionner, y compris les chargeurs de démarrage du système d'exploitation. (Sur le système patrimonial de PC, BIOS stocké dans le MBR peut être utilisé à la place.)

Le chargeur de démarrage est le 2ème étage du processus de démarrage qui est lancé par l'UEFI. Il charge l'image du noyau du système et l'image initrd dans la mémoire et leur donne le contrôle. Cette image initrd est l'image du système de fichiers racine et sa prise en charge dépend du chargeur de démarrage utilisé.

Le système Debian utilise normalement le noyau Linux comme noyau système par défaut. L’image initrd pour le noyau Linux 5.x actuel est techniquement l’image initramfs (système de fichiers initial en RAM).

Il existe de nombreux chargeurs de démarrage et de nombreuses options de configuration disponibles.


[Avertissement] Avertissement

Ne jouez pas avec les chargeurs de démarrage sans avoir un média de secours amorçable (clé USB,CD ou disquette) créé à partir des images du paquet grub-rescue-pc. Il vous permettra de démarrer votre système sans même avoir de chargeur de démarrage fonctionnel sur le disque dur.

Pour le système UEFI, GRUB2 lit d’abord la partition ESP et utilise l’UUID spécifié pour search.fs_uuid dans « /boot/efi/EFI/debian/grub.cfg » pour déterminer la partition du fichier de configuration du menu GRUB2 « /boot/grub/grub.cfg ».

La partie principale du fichier de configuration du menu GRUB2 ressemble à ceci :

menuentry 'Debian GNU/Linux' ... {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root fe3e1db5-6454-46d6-a14c-071208ebe4b1
        echo    'Loading Linux 5.10.0-6-amd64 ...'
        linux   /boot/vmlinuz-5.10.0-6-amd64 root=UUID=fe3e1db5-6454-46d6-a14c-071208ebe4b1 ro quiet
        echo    'Loading initial ramdisk ...'
        initrd  /boot/initrd.img-5.10.0-6-amd64
}

Pour cette partie de /boot/grub/grub.cfg, cette entrée de menu signifie ce qui suit.


[Astuce] Astuce

Vous pouvez activer l'affichage des messages du journal de démarrage du noyau en supprimant quiet dans « /boot/grub/grub.cfg ». Pour une modification persistante, veuillez modifier la ligne « GRUB_CMDLINE_LINUX_DEFAULT="quiet" » dans « /etc/default/grub ».

[Astuce] Astuce

Vous pouvez personnaliser l’image de démarrage GRUB en définissant la variable GRUB_BACKGROUND dans « /etc/default/grub » pointant vers le fichier d’image ou en plaçant le fichier d’image lui-même dans « /boot/grub/ ».

Consultez « info grub » et grub-install(8).

Le système mini-Debian est le troisième étage du processus d’amorçage lancée par le chargeur d’amorçage. Il lance le noyau du système avec son système de fichiers racine en mémoire. C’est un étage préparatoire facultatif du processus de démarrage.

[Note] Note

Le terme « système mini-Debian » est utilisé par l’auteur pour décrire dans ce document ce 3ème étage du processus de démarrage. On désigne souvent ce système par système initrd. Un système semblable en mémoire est utilisé par l’installateur Debian.

Le script « /init » est exécuté en tant que premier programme sur le système de fichiers racine en mémoire. C’est un script de l’interpréteur de commandes qui initialise le noyau dans l’espace utilisateur et passe le contrôle au prochain étage. Ce système mini-Debian offre au système d’amorçage une flexibilité comme l’ajout de modules du noyau avant le processus de démarrage principal ou le montage du système de fichiers racine en mode chiffré.

  • Le programme « /init » est un programme de script d’interpréteur si initramfs a été créé par initramfs-tools.

    • Vous pouvez interrompre cette partie du processus d’amorçage afin d’obtenir l’invite de l’interpréteur de l’administrateur en indiquant « break=init » etc. comme paramètre de démarrage du noyau. Consultez le script « /init » pour d’autres conditions d’interruption. Cet environnement d’interpréteur de commandes est suffisamment sophistiqué pour effectuer une bonne inspection du matériel de votre machine.

    • Les commandes disponibles avec ce système mini-Debian sont des commandes réduites et sont principalement fournies par un outil GNU appelé busybox(1).

  • Le programme « /init » est un programme exécutable de systemd si initramfs a été créé par dracut.

    • Les commandes disponibles dans ce mini-système Debian forment un environnement systemd(1) réduit à l’essentiel.

[Attention] Attention

Vous devrez utiliser l’option « -n » de la commande mount lorsque vous êtes sur le système de fichiers en lecture seule.

Le système Debian normal est le quatrième étage du processus d’amorçage, il est lancé par le système mini-Debian. Le noyau du système mini-Debian continue de tourner dans cet environnement. Le système de fichiers racine passe de celui en mémoire à celui, réel, lu sur le disque dur.

Le programme init est le premier à être exécuté, assorti du PID=1, afin qu’il accomplisse son rôle de processus principal de démarrage de plusieurs programmes. Le chemin par défaut du programme init est « /usr/sbin/init » mais il peut être modifié en passant un paramètre de démarrage au noyau, comme suit : « init=/chemin/vers/programme_init ».

« /usr/sbin/init » est lié symboliquement à « /lib/systemd/systemd » depuis Debian 8 Jessie (publiée en 2015).

[Astuce] Astuce

Il est possible de vérifier le niveau d’exécution actuel de la commande init du système avec la commande « ps --pid 1 -f ».


[Astuce] Astuce

Vous trouverez des conseils actualisés pour accélérer le processus de démarrage sur Debian wiki:BootProcessSpeedup.

Quand le système Debian démarre, /usr/sbin/init lié symboliquement avec /usr/lib/systemd est démarré comme processus de système init (PID=1) propriété du superutilisateur (UID=0). Consulter systemd(1).

Le processus d'initialisation de systemd génère des processus en parallèle en se basant sur les fichiers de configuration des unités (consulter systemd.unit(5)) qui sont écrits dans un style déclaratif au lieu du style procédural de type SysV.

Les processus engendrés sont placés dans des groupes de contrôle Linux individuels nommés d'après l'unité à laquelle ils appartiennent dans la hiérarchie privée de systemd (consulter cgroups et Section 4.7.5, « Caractéristiques de sécurité de Linux »).

Les unités pour le mode système sont chargés à partir du « Chemin de recherche d’unités système » décrit dans systemd.unit(5). Les principales sont les suivantes par ordre de priorité :

  • « /etc/systemd/system/* » : unités du système créés par l’administrateur ;

  • « /run/systemd/system/* » : unités d’exécution ;

  • « /lib/systemd/system/* » : unités du système installées par le gestionnaire de paquets de la distribution.

Leurs interdépendances sont spécifiées par les directives « Wants= », « Requires= », « Before= », « After= », ... (consulter « MAPPING OF UNIT PROPERTIES TO THEIR INVERSES » dans systemd.unit(5)). Les contrôles de ressources sont également définis (consulter systemd.resource-control(5)).

Le suffixe du fichier de configuration de l'unité encode leurs types comme :

  • *.service décrit le processus contrôlé et supervisé par systemd. Consulter systemd.service(5) ;

  • *.device décrit le périphérique exposé dans sysfs(5) en tant qu'arborescence de périphériques udev(7). Consulter systemd.device(5) ;

  • *.mount décrit le point de montage du système de fichiers contrôlé et supervisé par systemd. Consulter systemd.mount(5) ;

  • *.automount décrit le point de montage automatique du système de fichiers contrôlé et supervisé par systemd. Consulter systemd.automount(5) ;

  • *.swap décrit le périphérique ou le fichier d'échange contrôlé et supervisé par systemd. Consulter systemd.swap(5) ;

  • *.path décrit le chemin supervisé par systemd pour l'activation basée sur le chemin. Consulter systemd.path(5) ;

  • *.socket décrit le socket contrôlé et supervisé par systemd pour l’activation basée sur un socket. Consulter systemd.socket(5) ;

  • *.timer décrit la minuterie contrôlée et supervisée par systemd pour l’activation basée sur une minuterie. Consulter systemd.timer(5) ;

  • *.slice gère les ressources avec cgroups(7). Consulter systemd.slice(5) ;

  • *.scope est créé de manière programmatique à l’aide des interfaces de bus de systemd pour gérer un ensemble de processus système. Consulter systemd.scope(5) ;

  • *.target regroupe d'autres fichiers de configuration d’unité pour créer le point de synchronisation au démarrage. Consulter systemd.target(5).

Au démarrage du système (c’est-à-dire init), le processus systemd tente de démarrer le « /lib/systemd/system/default.target (normalement lié symboliquement lié à « graphical.target »). Tout d’abord, certaines unités cibles spéciales (consulter systemd.special(7)) telles que « local-fs.target », « swap.target » et « cryptsetup.target » sont extraites pour monter les systèmes de fichiers. Ensuite, d’autres unités cibles sont également extraites par les dépendances de l’unité cible. Pour plus d’informations, lisez bootup(7).

systemd offre des fonctionnalités de rétrocompatibilité. Les scripts de démarrage de style SysV dans « /etc/init.d/rc[0123456S].d/[KS]nom » sont toujours analysés et telinit(8) est traduit en demandes d’activation d’unité systemd.

[Attention] Attention

Les niveaux d’exécution émulés 2 à 4 sont tous liés symboliquement au même « multi-user.target ».

Le message d’erreur du noyau affiché sur la console peut être configuré en définissant son seuil :

# dmesg -n3

Sous systemd, les messages du noyau et du système sont consignés par le service de journal systemd-journald.service (alias journald) soit comme données binaires persistantes dans « /var/log/journal » ou comme données binaires volatiles dans « /run/log/journal/ ». Ces données binaires de journal sont accessibles avec la commande journalctl(1). Par exemple, vous pouvez afficher le journal du dernier démarrage avec :

$ journalctl -b

Sous systemd, l’utilitaire de journalisation du système rsyslogd(8) peut n’être pas installé. S’il est installé, il modifie son comportement pour lire les données binaires volatiles du journal (au lieu de la valeur par défaut avant systemd « /dev/log ») et pour créer des données ASCII permanentes traditionnelles de journal du système . Cela peut être personnalisé avec « /etc/default/rsyslog » et « /etc/rsyslog.conf » pour à la fois le fichier journal et l’affichage à l’écran. Voir rsyslogd(8) et rsyslog.conf(5). Voir aussi Section 9.3.2, « Analyseur de journaux ».

systemd offre non seulement un système d’initialisation, mais aussi des opérations génériques de gestion du système avec la commande systemctl(1).

Tableau 3.6. Liste de bribes de commande typiques utilisant journalctl

Opération bribe de commande
Lister toutes les types d’unités disponibles « systemctl list-units --type=aide »
Lister toutes les unités cibles en mémoire « systemctl list-units --type=target »
Lister toutes les unités de service en mémoire « systemctl list-units --type=service »
Lister toutes les unités de périphérique en mémoire « systemctl list-units --type=device »
Lister toutes les unités de montage en mémoire « systemctl list-units --type=mount »
Lister toutes les unités de sockets en mémoire « systemctl list-sockets »
Lister toutes les unités de minuterie en mémoire « systemctl list-timers »
Démarrer « $unit » « systemctl start $unit »
Stopper « $unit » « systemctl stop $unit »
Recharger une configuration particulière à un service « systemctl reload $unit »
Arrêter et démarrer tous les « $unit » « systemctl restart $unit »
Démarrer « $unit » et arrêter tous les autres « systemctl isolate $unit »
Basculer vers « graphical » (système GUI) « systemctl isolate graphical »
Basculer vers « multi-user » (système CLI) « systemctl isolate multi-user »
Basculer vers « rescue » (système CLI mono-utilisateur) « systemctl isolate rescue »
Envoyer le signal kill à « $unit » « systemctl kill $unit »
Vérifier si le service « $unit » est actif « systemctl is-active $unit »
Vérifier si le service « $unit » est défaillant « systemctl is-failed $unit »
Vérifier l’état de « $unit|$PID|périphérique » "systemctl status $unit|$PID|$device"
Afficher les propriétés de « $unit|$job » « systemctl show $unit|$job »
Réinitialiser « $unit » défaillant « systemctl reset-failed $unit »
Lister les dépendances de tous les services d’unités « systemctl list-dependencies --all »
Lister les fichiers d’unités installés sur le système « systemctl list-unit-files »
Activer « $unit » (ajout de lien symbolique) « systemctl enable $unit »
Désactiver « $unit » (suppression de lien symbolique) « systemctl disable $unit »
Démasquer « $unit » (suppression de lien symbolique vers « /dev/null ») « systemctl unmask $unit »
Masquer « $unit » (ajout de lien symbolique vers « /dev/null ») « systemctl mask $unit »
Obtenir le réglage de la cible par défaut « systemctl get-default »
Définir la cible par défaut à « graphical » (système à interface graphique) « systemctl set-default graphical »
Définir la cible par défaut à « multi-user » (système en ligne de commande) « systemctl set-default multi-user »
Afficher l’environnement de travail « systemctl show-environment »
Définir la « variable » d’environnement de travail à « valeur » « systemctl set-environment variable=valeur »
Rendre indéfini la « variable » d’environnement de travail « systemctl unset-environment variable »
Recharger tous les démons et fichiers d’unité « systemctl daemon-reload »
Arrêter le système « systemctl poweroff »
Arrêter et redémarrer le système « systemctl reboot »
Suspendre le système « systemctl suspend »
Hiberner le système « systemctl hibernate »

Ici, « $unit » dans les exemples ci-dessus peut être un nom d’unité unique (les suffixes tels que .service et .cible sont facultatifs) ou, dans de nombreux cas, des spécifications d’unité multiples (modèles génériques de type interpréteur « * », « ? », « [] » en utilisant fnmatch(3) qui seront comparés aux noms principaux de toutes les unités actuellement en mémoire).

Les commandes de modification d’état du système dans les exemples ci-dessus sont classiquement précédées par la commande « sudo » pour obtenir les droits d’administration nécessaires.

La sortie de « systemctl status $unit|$PID|$device » utilise des points de couleur (« ● ») pour examiner l’état de l’unité d’un seul coup d’œil.

  • Un « ● » blanc indique un état « inactif » ou « désactivation ».

  • Un « ● » rouge indique un état « échec » ou « erreur ».

  • Un « ● » vert indique un état « actif », « rechargement » ou « activation ».

Voici une liste d’autres bribes de commandes de surveillance sous systemd. Veuillez lire les pages de manuel pertinentes, y compris cgroups(7).


Les options de montage des systèmes ordinaires de fichiers de disque et en réseau sont définies dans « /etc/fstab ». Consulter fstab(5) et Section 9.6.7, « Optimisation du système de fichiers à l’aide des options de montage ».

La configuration du système de fichiers chiffré est définie dans « /etc/crypttab ». Consulter crypttab(5).

La configuration du RAID logiciel avec mdadm(8) est définie dans « /etc/mdadm/mdadm.conf ». Consulter mdadm.conf(5).

[Avertissement] Avertissement

Une fois tous les systèmes de fichiers montés, les fichiers temporaires se trouvant dans « /tmp », « /var/lock » et « /var/run » sont effacés lors de chaque démarrage du système.

L’instance du système d’infonuagique peut être lancée comme un clone des « Images officielles de Debian pour l’infonuagique » ou des images similaires. Pour une telle instance de système, les personnalités telles que le nom d’hôte, le système de fichiers, le réseautage, la régionalisation, les clés SSH, les utilisateurs et les groupes peuvent être configurées en utilisant des fonctionnalités fournies par les paquets cloud-init et netplan.io avec plusieurs sources de données telles que les fichiers placés dans l’image originelle du système et des données externes fournies lors de son amorçage. Ces paquets activent la configuration déclarative du système utilisant des données YAML.

Pour plus de détails, consulter « L’infonuagique avec Debian et ses descendants », la « documentation de Cloud-init » et la Section 5.4, « Configuration moderne de réseau pour l’infonuagique ».

Avec l'installation par défaut, de nombreux services réseau (consulter Chapitre 6, Applications réseau) sont démarrés comme processus démon après network.target au démarrage par systemd. Le démon « sshd » ne fait pas exception. Changeons donc cela pour un démarrage sur demande de « sshd » comme exemple de personnalisation.

Tout d’abord, désactivons l’unité de service du système installée.

 $ sudo systemctl stop sshd.service
 $ sudo systemctl mask sshd.service

Le système d’activation de socket à la demande des services Unix classiques passait par le superserveur inetd (ou xinetd). Sous systemd, l’équivalent peut être activé en ajoutant les fichiers de configuration d’unité *.socket et *.service.

sshd.socket pour indiquer un socket sur lequel écouté

[Unit]
Description=SSH Socket for Per-Connection Servers

[Socket]
ListenStream=22
Accept=yes

[Install]
WantedBy=sockets.target

sshd@.service comme fichier de service correspondant de sshd.socket

[Unit]
Description=SSH Per-Connection Server

[Service]
ExecStart=-/usr/sbin/sshd -i
StandardInput=socket

Puis rechargez.

 $ sudo systemctl daemon-reload

Le système udev fournit un mécanisme de découverte et d’initialisation automatique du matériel (consulter udev(7)) depuis le noyau 2.6 de Linux. Lors de la découverte de chaque périphérique par le noyau, le système udev lance un processus utilisateur qui utilise les informations provenant du système de fichiers sysfs (consulter Section 1.2.12, « procfs et sysfs »), charge les modules du noyau nécessaires pour sa prise en charge en utilisant le programme modprobe(8) (consulter la Section 3.9, « Initialisation des modules du noyau ») et crée les nœuds de périphérique en conséquence.

[Astuce] Astuce

Si « /lib/modules/kernel-version/modules.dep » n’a pas été proprement créé par depmod(8) pour quelque raison, les modules peuvent ne pas être chargés par le système udev comme on le souhaiterait. Lancez « depmod -a » pour corriger ce problème.

Les nœuds de périphériques n’ont pas besoin d’être statiques pour les règles de montage se trouvant dans « /etc/fstab ». Vous pouvez utiliser UUID à la place de leur nom de périphérique tel que« /dev/sda » pour monter les périphériques. Consultez Section 9.6.3, « Accès à une partition en utilisant l’UUID ».

Comme le système udev est une cible quelque peu mouvante, je laisse les détails pour d’autres documentations et je ne donnerai ici qu’un minimum d’informations.

[Avertissement] Avertissement

N’essayez pas d’exécuter des programmes d’exécution longue tels qu’un script de sauvegarde avec RUN dans les règles d’udev comme mentionné dans udev(7). Veuillez créer un fichier systemd.service(5) adéquat et l’activer (consulter la Section 10.2.3.2, « Sauvegarde déclenchée par des évènements de montage »).

Le programme modprobe(8) nous permet de configurer, depuis un processus utilisateur, un noyau Linux en cours d’exécution en ajoutant ou en supprimant des modules du noyau. Le système udev (consultez Section 3.8, « Le système udev ») en automatise l’appel afin d’aider à l’initialisation du module du noyau.

Il existe des modules non liés au matériel et des modules qui pilotent des éléments matériels particuliers comme les suivants qui demandent à être préchargés en les déclarant dans le fichier « /etc/modules » (consultez modules(5)).

Les fichiers de configuration du programme modprobe(8) se trouvent dans le répertoire « /etc/modprobes.d/ » comme c’est expliqué dans modprobe.conf(5). (Si vous souhaitez que certains modules du noyau ne soient pas chargés automatiquement, vous pouvez les mettre en liste noire dans le fichier« /etc/modprobes.d/blacklist ».)

Le fichier « /lib/modules/version/modules.dep » généré par le programme depmod(8) décrit les dépendances des modules utilisés par le programme modprobe(8).

[Note] Note

Si vous rencontrez des problèmes de chargement de modules lors du chargement des modules au démarrage ou avec modprobe(8), « depmod -a » peut résoudre ces problèmes en reconstruisant « modules.dep ».

Le programme modinfo(8) affiche des informations concernant les modules du noyau.

Le programme lsmod(8) formate de manière agréable le contenu de « /proc/modules », affichant quels sont les modules du noyau actuellement chargés.

[Astuce] Astuce

Vous pouvez identifier le matériel exact installé sur votre système. Consultez Section 9.5.3, « Identification du matériel ».

Vous pouvez configurer le matériel au moment du démarrage pour activer les fonctionnalités désirées de ce matériel. Consultez Section 9.5.4, « Configuration matérielle ».

Vous pouvez probablement ajouter la prise en charge d’un périphérique particulier en recompilant le noyau. Consultez Section 9.10, « Le noyau ».