6.12. Gestion de l'énergie

6.12.1. Généralités sur la gestion de l'énergie

La gestion de l'énergie sur les ordinateurs se fait classiquement via l'une des interfaces APM ou ACPI. APM (abréviation de « Advanced Power Management ») est la plus vieille, et s'appuyait essentiellement sur le BIOS pour prendre en charge la gestion de l'énergie. Elle peut encore n'être que la seule possibilité fonctionnelle sur la plupart des vieilles machines, mais est destinée à être remplacé par l'interface ACPI (abréviation de « Advanced Configuration and Power Interface »), développée par Intel. Cette nouvelle interface, bien que souffrant manifestement encore de quelques défauts de jeunesse, est nettement plus souple. En effet, elle se base sur un tout autre principe qu'APM, puisqu'elle permet cette fois de laisser le système prendre en charge la gestion de l'énergie. Étant donné que l'interface APM est vouée à disparaître, et sachant qu'on ne peut utiliser qu'une seule de ces interfaces, seule l'interface ACPI sera présentée dans ce document.

Le principe de fonctionnement de l'ACPI est le suivant. Le BIOS contient une table définie par le fabricant de l'ordinateur qui décrit le matériel fourni, et définit les opérations de base permettant de gérer l'énergie. Ces opérations sont définies dans un langage standard spécifié par Intel. Le système d'exploitation est en charge de lire ces informations et d'interpréter les opérations définies dans la table ACPI. Ainsi, c'est bien le système d'exploitation qui se charge de la gestion de l'ordinateur.

L'implémentation de l'interpréteur ACPI de Linux est l'implémentation de référence réalisée par Intel. Dans le meilleur des mondes, il ne devrait donc y avoir aucun problème pour utiliser l'ACPI sous Linux. Malheureusement, bon nombre de BIOS fournis par les fabricants sont bogués et ne respectent pas la norme ACPI. En effet, l'implémentation ACPI de Microsoft est incorrecte et son interpréteur accepte des erreurs de syntaxe que leur compilateur ACPI laisse passer (ce qui somme toute est cohérent, ils ne pouvaient pas faire moins sans que le résultat ne cesse de fonctionner). Ce n'est pas le cas de l'interpréteur ACPI de Linux puisque, par définition, elle ne peut se conformer à celle de Microsoft et être compatible bogue à bogue.

Le résultat est, hélas, catastrophique, puisque les fonctionnalités ACPI de ces machines ne peuvent pas être utilisées totalement sous Linux. Microsoft aurait voulu exploiter sa position dominante et corrompre le standard d'Intel pour isoler les concurrents qu'il n'aurait pas fait mieux (avis personnel). La seule solution est de récupérer la table ACPI du BIOS, de la désassembler pour en obtenir le code source, et de tenter de la recompiler avec le compilateur d'Intel (pas celui de Microsoft). Les erreurs apparaissent donc et peuvent ainsi être corrigées. Une fois la table ACPI corrigée, il faut soit convaincre le fabricant de l'ordinateur de mettre un nouveau BIOS à disposition, soit paramétrer le noyau pour qu'il charge cette table au lieu de prendre celle du BIOS pour argent comptant. Corriger une table ACPI boguée est une opéraiton extrêmement technique et absolument hors sujet, et faire en sorte que le noyau l'utilise nécessitait de patcher les sources du noyau jusqu'à la version 2.6.9. À présent, cela est faisable directement à partir du programme de configuration du noyau, mais je n'en parlerais pas plus ici. Vous pouvez consulter le site web de l'ACPI pour plus de détails à ce sujet. Si vous rencontrez des problèmes de ce type, je vous suggère de trouver un Linuxien confirmé, ou de faire une croix sur les fonctionnalités ACPI qui ne sont pas opérationnelles sous Linux.

6.12.2. Configuration de la gestion de l'énergie

La prise en charge des fonctionnalités de gestion d'énergie au niveau du noyau se fait simplement en activant les options correspondantes dans la configuration du noyau. Elles sont regroupées dans le menu « Power management options (ACPI, APM) ». Seules les plus intéressantes sont listées ci-dessous :

Les fonctionnalités ACPI prises en charge par le noyau sont exposées à l'utilisateur au travers des systèmes de fichiers virtuels /proc/ et /sys/.

Le répertoire /proc/acpi/ contient essentiellement un sous-répertoire pour chaque composant ACPI pris en charge par le noyau. Dans chacun de ces sous-répertoires, vous trouverez des fichiers contenant les informations courantes sur ces différents sous-systèmes.

Le sous-répertoire /sys/power/ vous permettra quant à lui de modifier le niveau d'économie d'énergie utilisé par votre ordinateur. En particulier, le fichier state vous permettra de le suspendre ou de le mettre en veille. Pour cela, il vous faut simplement écrire le mode désiré dans ce fichier avec la commande echo :

echo -n mode > /sys/power/state

mode est le mode désiré. Vous obtiendrez la liste des modes acceptés par Linux en lisant ce fichier avec la commande cat :

cat /sys/power/state

En général, les modes standby, mem et disk sont disponibles. standby correspond à la mise en veille simple de l'ordinateur. mem permet de réaliser une suspension du système en mémoire, et correspond donc à un niveau d'économie d'énergie supérieur. Enfin, disk permet d'éteindre complètement l'ordinateur après avoir stocké son état dans la partition d'échange. Cette commande correspond au niveau maximum d'économie d'énergie.

Note : Ces fonctionnalités sont relativement expérimentales et peuvent ne pas toutes fonctionner. Généralement, seul la suspension sur disque semble fonctionner, souvent sous condition que certains gestionnaires de périphériques soient déchargés avant la mise en veille.

Si vous disposez d'un portable, il est probable que votre processeur soit capable de fonctionner à différentes fréquences. Il est possible de lire la fréquence courante et de la modifier par l'intermédiaire des fichiers du répertoire /sys/devices/system/cpu/cpu0/cpufreq/. La fréquence courante peut être lue via le fichier cpuinfo_cur_freq. Il n'est pas possible de modifier directement cette valeur. Toutefois, le noyau donne la possibilité de la modifier via la politique de gestion d'énergie via le fichier scaling_governor. Les valeurs possibles pour ce fichier peuvent être lues dans le fichier scaling_available_governors.

Généralement, les politiques disponibles sont powersave et performance. Ces politiques permettent respectivement de changer la fréquence du processeur vers les fréquences indiquées dans les fichiers scaling_min_freq et scaling_max_freq. Ce sont donc dans ces fichiers que l'on pourra définir les fréquences utilisables. La liste des fréquences accessibles est fournie par le fichier scaling_available_frequencies.

6.12.3. Le démon ACPI

Le noyau expose les fonctionnalités de surveillance de l'ordinateur de l'interface ACPI via le fichier spécial de périphérique /proc/acpi/event. Dès qu'un événement se produit (passage de l'alimentation sur batterie pour un portable, hausse anormale de la température du processeur, appui sur le bouton de mise en marche / arrêt, etc.), une ligne signalant cet événement est ajoutée à ce fichier virtuel.

Les applications ne doivent pas lire ce fichier directement, cette tâche étant normalement attribuée au démon acpid. Ce démon surveille le fichier d'événement du noyau et fournit un mécanisme de notification plus générique (c'est à dire moins spécifique à Linux) aux applications. Ainsi, les applications peuvent se connecter au démon ACPI et être prévenue des événements que le noyau émet.

Le démon ACPI permet aussi de programmer des actions en réponse aux événements ACPI. Pour cela, il consulte les fichiers de configuration placés dans le répertoire /etc/acpi/events/ et exécute les actions qui y sont enregistrées.

Ces actions sont définies par des paires de lignes evénément / action permettant de renseigner, pour chaque type d'événement, l'action à effectuer. Les lignes de définition des événements utilisent des expressions rationnelles pour sélectionner les événements ou les groupes d'événements associés à l'action. Les lignes d'action quant à elles permettent d'indiquer la ligne de commande à exécuter en cas d'apparition de ces événements.

Par exemple, le fichier de configuration par défaut capte l'ensemble des événements ACPI et les passe aux script /etc/acpi/acpi_handler.sh à l'aide de ces deux simples lignes :

event=.*
action=/etc/acpi/acpi_handler.sh %e

L'expression rationnelle utilisée dans la ligne de définition des événements signale que toute chaîne de caractères doit correspondre. L'action en réponse est l'exécution du script acpi_handler.sh. La chaîne de caractères complète définissant l'événement est passée en premier paramètre et est représentée par le symbole %e.

Si les événements intéressants étaient tous les événements concernant le bouton d'alimentation de l'ordinateur, l'expression rationnelle utilisée aurait été la suivante :

event=button power.*

Comme vous pouvez le constater, le format utilisé pour les descriptions des événements envoyés par le noyau doit être connu pour pouvoir écrire les expressions rationnelles devant les sélectionner. Ces descriptions sont envoyées par le script par défaut acpi_handler.sh dans les fichiers de traces du système. Vous pourrez donc les y trouver après avoir généré les événements ACPI corresondants.

Pour donner un exemple, voici comment ce script peut être modifié afin de faire en sorte que la fermeture du couvercle d'un portable le mette en veille immédiatement sur disque :

#!/bin/sh

# Ajoute / à la liste des séparateurs pour le découpage de la ligne de commande :
IFS=${IFS}/
set $@

case "$1" in
  button)
    case "$2" in
      power) /sbin/init 0
         ;;
      # Traite l'événement de fermeture du couvercle :
      lid)
         # Vérifie que le couvercle est fermé :
         grep -q "close" /proc/acpi/button/lid/LID/state
         if [ $? -eq 0 ] ; then
            # Met en veille prolongée l'ordinateur :
            /usr/sbin/suspend.sh disk
         fi
         ;;
      # Trace les événements de type "bouton" non traités :
      *) logger "ACPI action $2 is not defined"
         ;;
    esac
    ;;
  # Trace tous les autres événements non traités :
  *)
    logger "ACPI group $1 / action $2 is not defined"
    ;;
esac

Ce script capte l'événement lid (« couvercle » en anglais) et vérifie l'état du capteur de fermeture du couvercle, accessible via le fichier d'état /proc/acpi/button/lid/LID/state (l'emplacement de ce fichier peut varier selon les ordinateurs). Si ce fichier indique que le couvercle est fermé, le script utilitaire suspend.sh est appelé pour mettre en veille l'ordinateur.

Ce dernier script utilise le fichier /sys/power/state pour effectuer cette mise en veille :

#!/bin/sh

# Stocke l'heure système (pour mise à jour de /etc/adjtime) :
hwclock --systohc

# Suspend le système et sur disque (méthode sûre) :
echo -n $1 > /sys/power/state

# Rétablit l'heure système :
hwclock --hctosys

Comme vous pouvez le constater, il est nécessaire de prendre en compte l'horloge système avant et après une suspension. En effet, sans cela, l'horloge système reprendrait exactement à la date de la suspension lors du réveil. Le stockage de l'heure courante avant suspension est également nécessaire, afin de maintenir le fichier de configuration /etc/adjtime cohérent.

Note : Une autre solution aurait été de faire le test sur l'état du bouton dans le script de suspension et d'appeler celui-ci directement en réponse à l'événement « button lid ».