11.15. Utiliser et déboguer l'ACPI sous FreeBSD
Précédent | Chapitre 11. Configuration et optimisation | Suivant

## 11.15. Utiliser et déboguer l'ACPI sous FreeBSD

Ecrit par Nate Lawson.
Avec la collaboration de Peter Schultz et Tom Rhodes.

L'ACPI est une nouvelle méthode de recherche des périphériques, de gestion de l'énergie, et fourni un accès standardisé à différents matériels gérés auparavant par le BIOS. Des progrès ont été fait vers un fonctionnement de l'ACPI sur tous les systèmes, mais des bogues dans le « bytecode » du langage machine ACPI (ACPI Machine Language—AML), des imperfections dans les sous-systèmes du noyau FreeBSD, et des bogues dans l'interpréteur ACPI-CA d'Intel® continuent d'apparaître.

Ce document est destiné à vous permettre d'aider les développeurs du système ACPI sous FreeBSD à identifier la cause originelle des problèmes que vous observez et à déboguer et développer une solution. Merci de lire ce document et nous espérons pouvoir résoudre les problèmes de votre système.

### 11.15.1. Soumettre des informations de débogage

### Note:

Avant de soumettre un problème, assurez-vous d'utiliser la dernière version de votre BIOS, et si elle est disponible, la dernière version du firmware du contrôleur utilisé.

Pour ceux désirant soumettre directement un problème, veuillez faire parvenir les informations suivantes à la liste freebsd-acpi@FreeBSD.org:

- Description du comportement défectueux, en ajoutant le type et le modèle du système et tout ce qui peut causer l'apparition du bogue. Notez également le plus précisément possible quand le bogue a commencé à se manifester s'il est nouveau.

- La sortie de dmesg(8) après un `boot -v`, y compris tout message généré lors de la manifestation du bogue.

- La sortie de dmesg(8) après un `boot -v` avec l'ACPI désactivé, si cette désactivation corrige le problème.

- La sortie de `sysctl hw.acpi`. C'est également un bon moyen de déterminer quelles fonctionnalités sont offertes par votre système.

- Une URL où peut être trouvé votre code source ACPI (ACPI Source Language—ASL). N'envoyez pas directement l'ASL sur la liste de diffusion, ce fichier peut être très gros. Vous pouvez générer une copie de votre ASL en exécutant la commande suivante:

      # acpidump -dt > name-system.asl

  (Remplacez `name` par votre nom d'utilisateur et `system` par celui du constructeur/modèle. Par exemple: `njl-FooCo6000.asl`)

La plupart des développeurs lisent la liste liste de diffusion à propos de la branche FreeBSD-CURRENT mais soumettez également les problèmes rencontrés à la liste freebsd-acpi afin d'être sûr qu'ils seront vus. Soyez patient, nous avons tous un travail à plein temps qui nous attend ailleurs. Si votre bogue n'est pas immédiatement apparent, nous vous demanderons probablement de soumettre un PR par l'intermédiaire de send-pr(1). Quand vous remplirez un PR, veillez à inclure les mêmes informations que celles précisées précédemment. Cela nous aidera à cerner et à résoudre le problème. N'envoyez pas de PR sans avoir contacté auparavant la liste freebsd-acpi étant donné que nous utilisons les PRs comme pense-bêtes de problèmes existants, et non pas comme mécanisme de rapport. Il se peut que votre problème puisse avoir déjà été signalé par quelqu'un d'autre.

### 11.15.2. Information de fond

L'ACPI est présent sur tous les ordinateurs modernes compatibles avec l'une des architectures ia32 (x86), ia64 (Itanium), et amd64 (AMD). La norme complète définit des fonctionnalités comme la gestion des performances du CPU, des contrôles des niveaux d'énergie, des zones de températures, divers systèmes d'utilisation des batteries, des contrôleurs intégrés, et l'énumération du bus. La plupart des systèmes n'implémentent pas l'intégralité des fonctionnalités de la norme. Par exemple, un ordinateur de bureau n'implémentera généralement que la partie énumération de bus alors qu'un ordinateur portable aura également le support de la gestion du refroidissement et de la batterie. Les ordinateurs portables disposent également des modes de mise en veille et de réveil, avec toute la complexité qui en découle.

Un système compatible ACPI dispose de divers composants. Les fabricants de BIOS et de circuits fournissent des tables de description (FADT) fixes en mémoire qui définissent des choses comme la table APIC (utilisée par les systèmes SMP), les registres de configuration, et des valeurs de configuration simples. De plus, est fournie une table de « bytecode » (la table différenciée de description du système—Differentiated System Description Table DSDT) qui spécifie sous forme d'une arborescence l'espace des noms des périphériques et des méthodes.

Le pilote ACPI doit analyser les tables, implémenter un interpréteur pour le « bytecode », et modifier les pilotes de périphériques et le noyau pour qu'ils acceptent des informations en provenance du sous-système ACPI. Pour FreeBSD, Intel® fourni un interpréteur (ACPI-CA) qui est partagé avec Linux et NetBSD. L'emplacement du code source de l'interpréteur ACPI-CA est `src/sys/contrib/dev/acpica`. Le code « glu » permettant à ACPI-CA de fonctionner sous FreeBSD se trouve dans `src/sys/dev/acpica/Osd`. Et enfin, les pilotes qui gèrent les différents périphériques ACPI se trouvent dans `src/sys/dev/acpica`.

### 11.15.3. Problèmes courants

Pour un fonctionnement correct de l'ACPI, il faut que toutes les parties fonctionnent correctement. Voici quelques problèmes courants, par ordre de fréquence d'apparition, et quelques contournements ou corrections possibles.

#### 11.15.3.1. Problèmes avec la souris

Dans certains cas le réveil après une mise en veille sera à l'origine d'un dysfonctionnement de la souris. Une solution connue est d'ajouter la ligne `hint.psm.0.flags="0x3000"` au fichier `/boot/loader.conf`. Si cela ne fonctionne pas, pensez à envoyer un rapport de bogue comme décrit plus haut.

#### 11.15.3.2. Mise en veille/réveil

L'ACPI dispose de trois modes de mise en veille en RAM (STR—Suspend To RAM), `S1` à `S3`, et un mode de mise en veille vers le disque dur (`STD`—Suspend To Disk), appelé `S4`. Le mode `S5` est un arrêt « soft » et est le mode dans lequel se trouve votre système quand il est branché mais pas allumé. Le mode `S4` peut être implémenté de deux manières différentes. Le mode `S4` BIOS est une mise en veille vers le disque assistée par le BIOS. Le mode `S4` OS est implémenté intégralement par le système d'exploitation.

Commencez par examiner la sortie de `sysctl hw.acpi` à la recherche d'éléments concernant les modes de mise en veille. Voici les résultats pour un Thinkpad:

    hw.acpi.supported_sleep_state: S3 S4 S5
    hw.acpi.s4bios: 0

Cela signifie que nous pouvons utiliser `acpiconf -s` pour tester les modes `S3`, `S4` OS, et `S5`. Si `s4bios` était égal à `1`, nous disposerions d'un support `S4` BIOS à la place de `S4` OS.

Quand vous testez la mise en veille et le réveil, commencez avec le mode `S1`, pour voir s'il est supporté. Ce mode doit fonctionner dans la plupart des cas puisqu'il nécessite peu de support. Le mode `S2` n'est pas implémenté, mais si vous en disposez, il est similaire au mode `S1`. La chose suivante à essayer est le mode `S3`. C'est le mode STR le plus avancé et il nécessite un support du pilote important pour réinitialiser correctement votre matériel. Si vous avez des problèmes au réveil de la machine, n'hésitez pas à contacter la liste freebsd-acpi mais ne vous attendez pas à ce que le problème soit résolu puisqu'il y a de nombreux pilotes/matériels qui nécessitent plus de tests et de développement.

Un problème courant avec la mise en veille/le réveil est que de nombreux pilotes de périphériques ne sauvegardent pas, ne restaurent pas, ou ne réinitialisent pas leurs logiciel, registres ou mémoire proprement. En premier lieu pour débogguer le problème, essayez:

    # sysctl debug.bootverbose=1
    # sysctl debug.acpi.suspend_bounce=1
    # acpiconf -s 3

Ce test émule le cycle de mise en veille/réveil de tous les pilotes de périphériques sans réellement passer dans l'état `S3`. Dans certains cas, les problèmes comme la perte de l'état du périphérique, le dépassement du délai du chien de garde du périphérique, les tentatives répétées, peuvent être capturés avec cette méthode. Notez que le système n'entrera pas vraiment dans l'état `S3`, ce qui signifie que les périphériques peuvent ne pas perdre leur alimentation, et nombreux fonctionneront correctement même si les méthodes de mise en veille/réveil sont totalement absentes, contrairement au cas d'un véritable état `S3`.

Les cas plus difficiles nécessitent un matériel supplémentaire, tel qu'un port série et un câble pour débogguer à l'aide d'une console série, un port firewire et un câble pour l'utilisation de dcons(4), et des compétences en debogguage du noyau.

Pour isoler le problème, retirez du noyau tous les pilotes de périphériques possibles. Si cela fonctionne, vous pouvez alors identifier le pilote fautif en chargeant les pilotes un à un jusqu'à l'apparition du problème. Généralement les pilotes binaires comme `nvidia.ko`, les pilotes d'affichage X11, ou les pilotes USB seront victimes de la plupart des problèmes tandis que ceux concernant les interfaces Ethernet fonctionneront normalement. Si vous pouvez charger/décharger les pilotes de périphériques correctement, vous pouvez automatiser cela en ajoutant les commandes appropriées dans les fichiers `/etc/rc.suspend` et `/etc/rc.resume`. Il y a un exemple en commentaire pour décharger ou charger un pilote. Essayez de fixer `hw.acpi.reset_video` à zéro (`0`) si votre affichage est corrompu après un réveil de la machine. Essayez des valeurs plus grandes ou plus faibles pour `hw.acpi.sleep_delay` pour voir si cela aide.

Une autre méthode est d'essayer de charger une distribution Linux récente avec le support ACPI et tester la mise en veille et le réveil sur le même matériel. Si cela fonctionne sous Linux, c'est probablement donc un problème de pilotes FreeBSD et déterminer quel pilote est responsable des dysfonctionnements nous aidera à corriger le problème. Notez que les personnes qui maintiennent l'ACPI sous FreeBSD ne s'occupe pas généralement des autres pilotes de périphériques (comme le son, le système ATA, etc.), aussi tout rapport concernant un problème de pilote devrait probablement en fin de compte être posté sur la liste freebsd-current et communiqué au responsable du pilote. Si vous vous sentez une âme d'aventurier, commencez à ajouter des printf(3)s de débogage dans un pilote problématique pour déterminer à quel moment dans sa fonction de réveil il se bloque.

Enfin, essayez de désactiver l'ACPI et d'activer l'APM à la place, pour voir si la mise en veille et le réveil fonctionnent avec l'APM, tout particulièrement dans le cas de matériel ancien (antérieur à 2000). Cela prend du temps aux constructeurs de mettre en place le support ACPI et le matériel ancien aura sûrement des problèmes de BIOS avec l'ACPI.

#### 11.15.3.3. Blocages du système (temporaires ou permanents)

La plupart des blocages système sont le résultat d'une perte d'interruptions ou d'une tempête d'interruptions. Les circuits ont beaucoup de problèmes en fonction de la manière dont le BIOS configure les interruptions avant le démarrage, l'exactitude de la table APIC (MADT), et le routage du System Control Interrupt (SCI).

Les tempêtes d'interruptions peuvent être distinguées des pertes d'interruptions en contrôlant la sortie de la commande `vmstat -i` en examinant la ligne mentionnant `acpi0`. Si le compteur s'incrémente plusieurs fois par seconde, vous êtes victime d'une tempête d'interruptions. Si le système semble bloqué, essayez de basculer sous DDB (CTRL+ALT+ESC sous la console) et tapez `show interrupts`.

Votre plus grand espoir quand vous faites face à des problèmes d'interruptions est d'essayer de désactiver le support APIC avec la ligne `hint.apic.0.disabled="1"` dans le fichier `loader.conf`.

#### 11.15.3.4. Paniques

Les paniques sont relativement rares dans le cas de l'ACPI et sont au sommet des priorités en matière de problèmes à corriger. Le premier point est d'isoler les étapes nécessaires à la reproduction de la panique (si possible) et d'obtenir une trace de débogage. Suivez l'aide sur l'activation de `options DDB` et la configuration d'une console série (lire la Section 27.6.1.1, « Entering the DDB Debugger from the Serial Line ») ou la configuration d'une partition dump(8). Vous pouvez obtenir une trace de débogage sous DDB avec la commande `tr`. Si vous devez recopier à la main la trace de débogage, assurez-vous de relever les cinq dernières lignes et les cinq premières ligne de la trace.

Ensuite essayez d'isoler le problème en démarrant avec l'ACPI désactivé. Si cela fonctionne, vous pouvez isoler le sous-système ACPI en utilisant différentes valeurs pour l'option `debug.acpi.disable`. Consultez la page de manuel acpi(4) pour des exemples.

#### 11.15.3.5. Le système redémarre après une mise en veille ou un arrêt

Tout d'abord, essayez de fixer `hw.acpi.disable_on_poweroff="0"` dans loader.conf(5). Cela empêche l'ACPI de désactiver divers événements lors du processus d'arrêt. Certains systèmes ont besoin d'avoir cette valeur fixée à `1` (valeur par défaut) pour la même raison. Cela corrige généralement le problème d'un système démarrant spontanément après une mise en veille ou un arrêt.

#### 11.15.3.6. Autres problèmes

Si vous rencontrez d'autres problèmes avec l'ACPI (impossible de travailler avec une station d'amarrage, périphériques non détectés, etc.), veuillez envoyer un courrier descriptif à la liste de diffusion; cependant, certains de ces problèmes peuvent être relatifs à des partie incomplètes du sous-système ACPI et qui pourront prendre du temps à être implémentées. Soyez patient et prêt à tester les correctifs que nous pourront éventuellement vous envoyer.

### 11.15.4. ASL, `acpidump`, et IASL

Le problème le plus courant est le fait que les constructeurs fournissent des « bytecodes » erronés (ou plus simplement bogués!). Cela se manifeste généralement sur la console par des messages du noyau du type:

    ACPI-1287: *** Error: Method execution failed [\\_SB_.PCI0.LPC0.FIGD._STA] \\
    (Node 0xc3f6d160), AE_NOT_FOUND

La plupart du temps vous pouvez corriger ces problèmes en mettant à jour votre BIOS avec la dernière version disponible. La majorité des messages sur la console sont inoffensifs mais si vous avez d'autres problèmes comme l'état de la batterie qui ne fonctionne pas, ce sont de bonnes raisons pour commencer à jeter un oeil à ces problèmes dans l'AML. Le « bytecode », connu sous le nom d'AML, est compilé à partir d'un langage source appelé ASL. L'AML se trouve dans une table appelée DSDT. Pour obtenir une copie de votre ASL, utilisez acpidump(8). Vous devriez utiliser de paire les options `-t` (qui affiche le contenu des tables fixes) et `-d` (qui désassemble l'AML en ASL). Consultez la section Soumettre des informations de déboguage pour un exemple de syntaxe.

Le tout premier test que vous pouvez effectuer est de recompiler votre ASL à la recherche d'erreurs. Les avertissements peuvent être généralement ignorés mais les erreurs sont des bogues qui normalement empêchent l'ACPI de fonctionner correctement. Pour recompiler votre ASL, utilisez la commande suivante:

    # iasl your.asl

### 11.15.5. Correction de votre ASL

A long terme, notre objectif est que tout le monde puisse avoir un système ACPI fonctionnant sans aucune intervention de l'utilisateur. Actuellement, nous sommes toujours en train de développer des solutions pour contourner les erreurs courantes faites par les fabricants de BIOS. L'interpréteur de Microsoft® (`acpi.sys` et `acpiec.sys`) ne contrôle pas de façon stricte la conformité avec la norme, et par conséquent de nombreux fabricants de BIOS qui testent l'ACPI uniquement sous Windows® ne corrigent donc jamais leur ASL. Nous espérons poursuivre à identifier et documenter avec exactitude les comportements non-standards autorisés par l'interpréteur de Microsoft® et les reproduire de manière à permettre à FreeBSD de fonctionner sans obliger les utilisateurs à corriger leur ASL. Comme solution et pour nous aider à identifier ces comportements, vous pouvez corriger manuellement votre ASL. Si cela fonctionne pour vous, veuillez nous envoyer un diff(1) de l'ancien et du nouveau ASL de façon à ce que nous puissions corriger le comportement incorrect dans ACPI-CA et rendre donc inutile à l'avenir votre correctif.

Voici une liste des messages d'erreur courants, leur cause, et comment les corriger:

#### 11.15.5.1. Dépendances _OS

Certains AMLs supposent que le monde n'est fait de que différentes versions de Windows®. Vous pouvez demander à FreeBSD de s'annoncer comme étant n'importe quel système d'exploitation pour voir si cela corrige les problèmes que vous pouvez rencontrer. Une manière simple de faire cela est de fixer la variable `hw.acpi.osname="Windows 2001"` dans `/boot/loader.conf` ou avec une autre chaîne de caractères que vous trouvez dans l'ASL.

#### 11.15.5.2. Missing Return statements

Certaines méthodes ne renvoient pas explicitement une valeur comme la norme le demande. Bien qu'ACPI-CA ne gère pas cela, FreeBSD contourne ce problème en renvoyant implicitement la valeur. Vous pouvez également ajouter des « Return statements » explicites où cela est nécessaire si vous connaissez la valeur à renvoyer. Pour forcer `iasl` à compiler l'ASL, utilisez l'option `-f`.

#### 11.15.5.3. Remplacer l'AML par défaut

Après avoir personnalisé `votre.asl`, vous voudrez le compiler, pour cela exécutez:

    # iasl your.asl

Vous pouvez ajouter l'option `-f` pour forcer la création de l'AML, même s'il y a des erreurs lors de la compilation. Rappelez-vous que certaines erreurs (e.g., missing Return statements) sont automatiquement contournées par l'interpréteur.

`DSDT.aml` est le fichier de sortie par défaut pour `iasl`. Vous pouvez le charger à la place de la version boguée de votre BIOS (qui est toujours présent dans la mémoire flash) en éditant le fichier `/boot/loader.conf` comme suit:

    acpi_dsdt_load="YES"
    acpi_dsdt_name="/boot/DSDT.aml"

Assurez-vous de bien copier votre fichier `DSDT.aml` dans le répertoire `/boot`.

### 11.15.6. Obtenir d'ACPI une sortie de débogage

Le pilote ACPI dispose d'une fonction de débogage très flexible. Elle vous permet de spécifier un ensemble de sous-systèmes ainsi que le niveau de verbosité. Les sous-systèmes que vous désirez déboguer sont indiqués sous la forme de « couches » et sont divisés en composants ACPI-CA (ACPI_ALL_COMPONENTS) et en supports matériel ACPI (ACPI_ALL_DRIVERS). La verbosité de la sortie de débogage est spécifiée par un « niveau » et des intervalles de ACPI_LV_ERROR (rapporte juste les erreurs) à ACPI_LV_VERBOSE (tout). Le « niveau » est un masque de bits séparés par des espaces, aussi de nombreuses options peuvent être fixées à la fois. Dans la pratique, vous voudrez utiliser un console série pour afficher la sortie si les informations de débogage sont si importantes qu'elles dépassent le tampon des messages de la console. Une liste complète des couches individuelles et des niveaux peut être trouvée dans la page de manuel acpi(4).

L'affichage des informations de débogage n'est pas activé par défaut. Pour l'activer, ajoutez la ligne `options ACPI_DEBUG` à votre fichier de configuration du noyau si l'ACPI est compilé dans le noyau. Vous pouvez ajouter la ligne `ACPI_DEBUG=1` à votre fichier `/etc/make.conf` pour l'activer de façon globale. Si l'ACPI est sous forme de module, vous pouvez recompiler votre module `acpi.ko` comme suit:

    # cd /sys/modules/acpi/acpi
    && make clean &&
    make ACPI_DEBUG=1

Installez `acpi.ko` dans le répertoire `/boot/kernel` et indiquez le niveau et la couche désirée dans `loader.conf`. L'exemple suivant active les messages de débogage pour tous les composants ACPI-CA et tous les pilotes de matériel ACPI (CPU, LID, etc.). Il n'affichera que les messages d'erreur, c'est le niveau le moins verbeux.

    debug.acpi.layer="ACPI_ALL_COMPONENTS ACPI_ALL_DRIVERS"
    debug.acpi.level="ACPI_LV_ERROR"

Si l'information que vous voulez est déclenchée par un événement particulier (disons par exemple une mise en veille suivi d'un réveil), vous pouvez abandonner les modifications dans `loader.conf` et utiliser à la place `sysctl` pour indiquer la couche et le niveau après le démarrage et préparer votre système pour cet événement particulier. Les variables `sysctl` sont appelées de la même manière que dans le fichier `loader.conf`.

### 11.15.7. Références

Plus d'information au sujet de l'ACPI peut être trouvé aux emplacements suivants:

- La liste de diffusion liste de diffusion concernant ACPI sous FreeBSD

- Les archives de la liste de diffusion ACPI `http://lists.freebsd.org/pipermail/freebsd-acpi/`

- Les archives de l'ancienne liste de diffusion ACPI `http://home.jp.FreeBSD.org/mail-list/acpi-jp/`

- La spécification ACPI 2.0 `http://acpi.info/spec.htm`

- Les pages de manuel: acpi(4), acpi_thermal(4), acpidump(8), iasl(8), acpidb(8)

- Ressource sur le débogage de la DSDT. (Utilise un exemple basé sur du matériel Compaq mais qui est en général intéressant.)

Précédent | Niveau supérieur | Suivant
11.14. Gestion de l'énergie et des ressources | Sommaire | Chapitre 12. Processus de démarrage de FreeBSD

Ce document, ainsi que d'autres peut être téléchargé sur ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

Pour toutes questions à propos de FreeBSD, lisez la documentation avant de contacter <questions@FreeBSD.org>.
Pour les questions sur cette documentation, contactez <doc@FreeBSD.org>.