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.
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.
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
.
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.
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.
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.
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
.
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.
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.
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.
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
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:
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.
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
.
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
.
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
.
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.)
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>.