ACPI is een totaal nieuwe manier om apparaten te ontdekken, om energieverbruik te beheren en om een gestandaardiseerde toegang te bieden tot allerlei apparaten die eerder via het BIOS beheerd werden. Er wordt voortdurend vooruitgang geboekt om ACPI op alle systemen te laten werken, maar bugs in de ACPIMachine Language (AML) bytecode van sommige moederborden, onvolledigheden in de subsystemen van de kernel van FreeBSD en bugs in de Intel® ACPI-CA interpreter blijven opduiken.
Deze tekst is bedoeld om u te helpen met het bijstaan van de FreeBSD ACPI beheerders met het vinden van de hoofdoorzaken van problemen die u opmerkt en met het debuggen en het vinden van een oplossing.
Voordat een probleem wordt gemeld, moet het zeker zijn dat de laatste BIOS versie draait en indien beschikbaar de geïntregeerde controller firmware versie.
Diegenen die meteen een probleem willen indienen, sturen de volgende informatie naar freebsd-acpi@FreeBSD.org:
Omschrijving van het foutieve gedrag, inclusief systeemtype en -model en alles wat de fout kan veroorzaken. Als het een nieuw fenomeen is, dan dient ook zo accuraat mogelijk aangegeven te worden wanneer de fout het eerst optrad.
De uitvoer van dmesg(8) van boot
-v
, inclusief foutmeldingen die gegenereerd
worden als de fout optreedt.
De uitvoer van dmesg(8) van boot
-v
met ACPI uitgeschakeld,
indien het uitzetten van ACPI het
probleem oplost.
Uitvoer van sysctl hw.acpi
. Dit is
tevens een goede manier om uit te vinden welke
ACPI-mogelijkheden een systeem
heeft.
Een URL waar de ACPISource Language (ASL) gevonden kan worden. De ASL dient niet rechtstreeks naar de lijst gezonden te worden, omdat deze nogal groot kan zijn. Een kopie van een ASL kan gemaakt worden met het volgende commando:
#
acpidump -dt > naam-systeem.asl
(Vervang uw aanmeldnaam door
$NAME
en producent/model door
$SYSTEM
. Bijvoorbeeld:
njl-FooCo6000.asl
)
De meeste FreeBSD-programmeurs lezen de FreeBSD-CURRENT mailinglijst, maar problemen gaan bij voorkeur ook naar freebsd-acpi zodat ze zeker gezien worden. Het kan enige tijd duren voordat er antwoord komt, omdat deze mensen elders ook nog volledige banen hebben. Als de bug niet meteen duidelijk is, komt er waarschijnlijk en verzoek om een PR in te dienen via send-pr(1). Als er een PR moet worden opgesteld, dan dient alle hierboven gevraagde informatie vermeld te worden. Dit helpt om het probleem te kunnen volgen en oplossen. Het sturen van een PR zonder eerst freebsd-acpi te mailen is niet wenselijk, aangezien men PRs gebruikt als herinnering van bestaande problemen, niet als rapportagesysteem. Mogelijk is een probleem al eens door iemand anders gemeld.
ACPI is aanwezig op alle moderne computers die voldoen aan de ia32 (x86), ia64 (Itanium) of amd64 (AMD) architecturen. De volledige standaard heeft vele mogelijkheden zoals CPU-prestatiebeheer, energiebeheer, thermische zones, diverse batterijsystemen, ingebedde controllers en busnummering. De meeste systemen implementeren minder dan de volledige standaard. Een desktopsysteem implementeert bijvoorbeeld meestal alleen busnummering, terwijl laptops mogelijk ook koeling- en batterijbeheer ondersteunen. Laptops hebben ook suspend en resume (slapen en wakker worden) met hun eigen aanverwante comlexiteit.
Een ACPI-compliant systeem heeft verscheidene componenten. Het BIOS- en chipsetverkopers bieden verscheidene vaste tabellen aan zoals FADT in het geheugen die zaken als de APIC-afbeelding (gebruikt voor SMP), configuratieregisters, en eenvoudige configuratiewaarden specificeren. Ook wordt er een tabel van bytecode (de Differentiated System Description Table of DSDT) geleverd die een op een boomstructuur lijkende namespace biedt voor apparaten en methoden.
Het stuurprogramma ACPI moet de
voorgedefinieerde tabellen verwerken, een interpreter voor de
bytecode implementeren en apparaatstuurprogramma's en de kernel
aanpassen om informatie van het
ACPI-subsysteem te accepteren. Intel® heeft
een interpreter beschikbaar gesteld (ACPI-CA)
die door FreeBSD en ook door Linux® en NetBSD gebruikt wordt. De
ACPI-CA-broncode staat in src/sys/contrib/dev/acpica
. De
lijmcode die ACPI-CA laat werken met FreeBSD
staat in src/sys/dev/acpica/Osd
.
Stuurprogramma's die verscheidene
ACPI-apparaten implementeren staan in
src/sys/dev/acpica
.
Wil ACPI goed werken, dan moeten alle onderdelen goed werken. Hieronder staan enkele algemene problemen in volgorde van hoe vaak ze optreden en enkele mogelijke oplossingen of manieren om de problemen te vermijden.
Soms doet een muis het niet bij het opstarten uit de
slaapstand. Een bekend lapmiddel is het toevoegen van
hint.psm.0.flags="0x3000"
aan
/boot/loader.conf
. Als dat niet werkt,
dan wordt aangeraden een bugrapport in te sturen, zoals
eerder is beschreven.
ACPI heeft drie slaapstanden waarbij
het geheugen (RAM) wordt ingezet. Dit
zijn de STR-toestanden
S1
-S3
, en nog een
slaap-met-gebruik-van-harde-schijf toestand
(STD
) die S4
heet.
S5
is “zacht uit” en is de
normale status van een systeem als het is aangesloten maar
niet is aangezet. S4
kan feitelijk op twee
manieren geïmplementeerd worden:
S4
BIOS is een slaapstand
naar schijf met behulp van het BIOS en
S4
OS wordt volledig door
het besturingssysteem geïmplenteerd.
als eerste dienen de sysctl hw.acpi
items die iets met de slaapstand te maken hebben gecontroleerd
te worden. Hieronder staan de resultaten voor een
Thinkpad:
hw.acpi.supported_sleep_state: S3 S4 S5 hw.acpi.s4bios: 0
Dit betekent dat hier acpiconf -s
gebruikt kan worden om S3
,
S4
OS en
S5
te testen. Als s4bios
gelijk was aan (1
), dan zou er
S4
BIOS ondersteuning
zijn in plaats van S4
OS.
Als suspend/resume getest moet worden, dient, indien
ondersteund, bij S1
begonnen te worden.
Deze toestand heeft de grootste kans om te werken, omdat deze
niet veel stuurprogrammaondersteuning vereist. Niemand heeft
nog S2
geïmplementeerd, maar het is
ongeveer hetzelfde als S1
. Daarna wordt
S3
getest. Dit is het diepste
STR-niveau en heeft uitgebreide
ondersteuning van stuurprogramma's nodig om hardware goed
opnieuw te kunnen starten. Mochten er blokkades optreden,
dan kan naar de freebsd-acpi lijst gemaild worden. Er kan
echter geen snelle oplossing verwacht worden, omdat er nog de
nodige stuurprogramma's/hardware liggen om getest en bewerkt
te worden.
Een veelvoorkomend probleem met suspend/resume is dat veel apparaatstuurprogramma's hun firmware, registers of apparaatgeheugen niet fatsoenlijk opslaan, herstellen, of herinitialiseren. Een eerste poging om het probleem te vinden omvat:
#
sysctl debug.bootverbose=1
#
sysctl debug.acpi.suspend_bounce=1
#
acpiconf -s 3
Deze test emuleert de suspend/resume-cyclus van alle
apparaten zonder daadwerkelijk naar de toestand S3
te gaan. In sommige gevallen kunt u zo eenvoudig problemen
vaststellen (bijvoorbeeld het verliezen van de firmware-toestand,
timeout van de apparaatwaakhond, en steeds opnieuw iets proberen).
Merk op dat het systeem niet werkelijk naar de toestand
S3
gaat, wat inhoudt dat apparaten geen spanning
verliezen waardoor velen prima zullen werken zelfs als de
suspend/resume-methoden geheel ontbreken, dit in tegenstelling tot de
echte toestand S3
.
Moeilijkere gevallen vereisen aanvullende hardware, dat is een serieële poort/kabel voor de serieële console of een Firewire poort/kabel voor dcons(4), en vaardigheden in het debuggen van de kernel.
Om een probleem te kunnen isoleren helpt het om zoveel
mogelijk stuurprogramma's uit de kernel te halen. Als dit
werkt, kan er teruggewerkt worden naar het stuurprogramma dat
schuldig is aan het falen. Meestal vertonen binaire
stuurprogramma's als nvidia.ko
, X11
beeldschermstuurprogramma's en USB de
meeste problemen, terwijl bijvoorbeeld Ethernet-interfaces
meestal meteen goed werken. Als de stuurprogramma's zonder
problemen geladen en verwijderd kunnen worden, dan is dit te
automatiseren door de juiste commando's in
/etc/rc.suspend
en
/etc/rc.resume
te zetten. Er staat een
voorbeeld (achter commentaartekens) voor het laden en
verwijderen van een stuurprogramma. Als het beeldscherm er na
wakker worden vreemd uitziet, kan geprobeerd worden
hw.acpi.reset_video
op nul te zetten. Met
langere of kortere waarden voor
hw.acpi.sleep_delay
kan bekeken worden of dat
helpt.
In geval van problemen is het ook een optie om een recente Linux® distibutie met ondersteuning voor ACPI support te starten en daarvan de suspend/resume ondersteuning op dezelfde hardware uit te proberen. Als het werkt met Linux®, dan is het waarschijnlijk een FreeBSD stuurprogrammaprobleem en als het mogelijk is uit te vinden over welk stuurprogramma het gaat, kan dat bijdragen aan het oplossen van het probleem. ACPI houdt zich in het algemeen niet bezig met andere stuurprogramma's zoals geluid, ATA, enzovoort. Als er dus een echt probleem met een stuurprogramma is, dan is waarchijnlijk uiteindelijk ook nodig naar de freebsd-current lijst te posten en naar de beheerder van het stuurprogramma. Voor degenen met moed is het vooral aan te raden een paar printf(3)s in problematische stukken van een stuurprogramma te plaatsen voor debugging om na te gaan waar de resumefunctie precies hangt.
Tot slot kan geprobeerd worden om ACPI uit te zetten en in plaats daarvan APM aan te zetten. Als suspend/resume werkt met APM, is het wellicht verstandig het daarbij te houden, vooral met wat oudere apparatuur (voor 2000). Producenten hebben nogal wat tijd nodig gehad om ACPI ondersteuning goed te krijgen en voor oudere hardware is het waarschijnlijker dat er BIOS-problemen zijn met ACPI.
Meestal is het hangen van het systeem het gevolg van verloren interrupts of een interruptstorm. Chipsets kunnen een heleboel problemen hebben, afhankelijk van hoe het BIOS interrupts instelt voor het opstarten, of de APIC (MADT) tabel correct is en de routering van het System Control Interrupt (SCI).
Interruptstorms kunnen onderscheiden worden van verloren
geraakte interrupts door de uitvoer van vmstat
-i
te controleren en de regel met
acpi0
goed te lezen. Als de teller in
toenemende mate hoger staat dan enkele per seconde, dan is
sprake van een interruptstorm. Als het systeem lijkt te
hangen, is het wellicht nog mogelijk door te dringen tot
de DDB (CTRL+ALT+ESC) en
show interrupts
uit te voeren.
De beste hoop in geval van interruptproblemen is om
APIC-ondersteuning uit te zetten met
hint.apic.0.disabled="1"
in
loader.conf
.
Panics zijn relatief zeldzaam met ACPI
en krijgen de hoogste prioriteit bij het oplossen. Eerst
moeten de verschillende gebeurtenissen waarmee de panic (als
mogelijk) te reproduceren is geïsoleerd worden en moet
een backtrace gemaakt worden. options DDB
dient aangezet te worden en er dient een seriële
console (Paragraaf 26.6.5.3, “De debugger DDB gebruiken via de seriële
verbinding”) of een
dump(8) partitie te komen. In DDB is
een backtrace te maken met tr
. Als de
backtrace handmatig opgeschreven moet worden, is het
belangrijk dat in ieder geval de bovenste en onderste vijf (5)
regels van de backtrace genoteerd worden.
Daarna dient getracht te worden het systeem te starten
zonder ACPI. Als dat werkt, is het
ACPI-subsysteem geïsoleerd en kunnen
de verschillende debug.acpi.disable
-waarden
uitgeprobeerd worden. In acpi(4) staan enkele
voorbeelden.
hw.acpi.disable_on_poweroff="0"
kan
uitgezet worden in loader.conf(5). Hierdoor schakelt
ACPI bepaalde gebeurtenissen tijdens het
afsluitproces niet uit. Om dezelfde redenen moeten sommige
systemen deze waarde altijd op 1
(standaard) hebben staan. In het algemeen lost dit een
probleem op waarbij een systeem spontaan weer opkomt nadat het
in slaapstand is gezet of geheel gestopt is.
Als er nog andere problemen zijn met ACPI (met een docking station of apparaten niet gedetecteerd, enzovoort), dan kan een mail met beschijving naar de mailinglijst gezonden worden. Sommige zaken kunnen echter gerelateerd zijn aan delen van het ACPI-subsysteem die nog niet af zijn, dus het kan in sommige gevallen een tijd duren. Gebruikers moeten soms geduld en de bereidheid om eventuele patches uit te proberen hebben.
Het grootste probleem is dat BIOS-producenten vaak incorrecte (of gewoon foutieve) bytecode leveren. Dit blijkt doorgaans uit kernelboodschappen als:
ACPI-1287: *** Error: Method execution failed [\\_SB_.PCI0.LPC0.FIGD._STA] \\ (Node 0xc3f6d160), AE_NOT_FOUND
Vaak kunnen dergelijke problemen geoplost worden door de
BIOS bij te werken tot de laatste revisie.
De meeste consoleberichten zijn onschuldig, maar als er andere
problemen zijn, zoals batterijstatus die niet werkt, dan ligt
het voor de hand te zoeken naar problemen in de
AML-code. De bytecode die
AML genoemd wordt, wordt gecompileerd van een
broncodetaal ASL. Deze staat weer in een
tabel DSDT. Met acpidump(8) kan een
kopie van de ASL gemaakt worden. Dan moeten
zowel de opties -t
(laat inhoud van vaste
tabellen zien) als -d
(disassembleer
AML naar ASL) gebruikt
worden. In Debuginformatie
aanleveren staat een voorbeeld.
De eenvoudigste eerste controle is de ASL-code opnieuw compileren en kijken of er foutmeldingen optreden. Waarschuwingen kunnen doorgaans genegeerd worden, maar fouten zijn bugs die er meestal toe leiden dat ACPI niet correct werkt. Om ASL te hercompileren:
#
iasl eigen.asl
Op langere termijn is het de bedoeling dat voor vrijwel elke
machine ACPI werkt zonder enig ingrijpen van
de gebruiker. Op dit moment wordt er echter nog gewerkt aan
oplossingen voor veel voorkomende vergissingen die
BIOS-producenten maken. De Microsoft®
interpreter (acpi.sys
en
acpiec.sys
) controleert niet strikt of het
BIOS volledig aan de standaard voldoet,
waardoor het voorkomt dat BIOS-makers die
alleen testen onder Windows® bepaalde fouten in hun
ASL nooit correct repareren. FreeBSD hoopt door
te gaan met de identificatie en documentatie van welk
niet-standaard gedrag precies wordt toegelaten door
Microsoft®'s interpreter en te dit te repliceren zodat FreeBSD
kan werken zonder dat gebruikers zich gedwongen zien om de
ASL te repareren. Als een tijdelijke
oplossing en om te helpen met het in kaart brengen van bepaald
gedrag, kan de ASL handmatig gerepareerd
worden. Mocht dit lukken, dan wordt erop aangedrongen een
diff(1) van de oude en de nieuwe ASL te
mailen, zodat het foutieve gedrag mogelijk in
ACPI-CA kan worden verwerkt, waardoor andere
gebruikers niet meer handmatig met hun ASL
aan de gang hoeven.
Hieronder staat een lijst algemene foutmeldingen, hun oorzaken en hoe ze op te lossen:
Sommige AMLs gaan ervan uit dat de
wereld enkel bestaat uit Windows® versies. FreeBSD kan zich
voordoen als elk OS om te kijken of dit
problemen oplost. Een gemakkelijke manier om dit te doen is
hw.acpi.osname="Windows 2001"
in te stellen
in /boot/loader.conf
of andere
gelijksoortige strings die in een ASL
staan.
Sommige methoden hebben geen specifieke returnwaarde,
zoals wel vereist wordt door de standaard. Hoewel
ACPI-CA hier niets mee doet, heeft FreeBSD
de mogelijkheid tot impliciete returns. Er kunnen ook
expliciete return-opdrachten toegevoegd worden waar vereist,
als het bekend is welke waarden teruggevoerd moeten worden.
Om iasl
te dwingen tot compilatie van
ASL kan de schakeloptie
-f
gebruikt worden.
Nadat eigen.asl
aangepast is, kan
deze als volgt gecompileerd worden:
#
iasl eigen.asl
Met de optie -f
is af te dwingen dat de
AML gemaakt wordt, zelfs als er
compileerfouten optreden. Sommige fouten (zoals ontbrekende
return-opdrachten) worden automatisch opgelost door de
interpreter.
DSDT.aml
is de standaardnaam voor het
bestand dat door iasl
wordt geproduceerd.
Dit is in plaats van de foutieve versie uit het
BIOS (die nog steeds aanwezig is in het
flashgeneugen) te laden door
/boot/loader.conf
als volgt te
wijzigen:
acpi_dsdt_load="YES" acpi_dsdt_name="/boot/DSDT.aml"
DSDT.aml
moet in de map /boot
staan.
Het stuurprogramma ACPI heeft een zeer flexibele debugfaciliteit. Er kan zowel een verzameling van subsystemen aangegeven worden als het niveau van uitvoerigheid. De te debuggen subsystemen worden aangegeven als lagen (“layers”) en zijn opgedeeld in ACPI-CA-componenten (ACPI_ALL_COMPONENTS) en ACPI-hardware-ondersteuning (ACPI_ALL_DRIVERS). De uitvoerigheid van debuguitvoer wordt aangegeven als het niveau (“level”) en gaat van CPI_LV_ERROR (alleen fouten rapporteren) tot ACPI_LV_VERBOSE (alles). Het niveau is een bitmasker en dus kunnen er meerdere opties tegelijk ingeschakeld worden (gescheiden door spaties). In de praktijk wordt wellicht een seriële console gebruikt om de uitvoer te loggen als deze zo omvangrijk is dat de console berichtbuffer vol loopt (misschien wel meerdere keren). Een complete lijst van de individuele lagen en niveaus staat in acpi(4).
Debuguitvoer staat standaard niet aan. Door
options ACPI_DEBUG
toe te voegen aan het
bestand met kernelinstellingen als ACPI als
de kernel is gebouwd, wordt het ingeschakeld. Door
ACPI_DEBUG=1
toe te voegen aan
/etc/make.conf
wordt het systeembreed
ingeschakeld. Als ACPI als module wordt
gebruikt (de normale situatie), dan hoeft slechts de module
acpi.ko
opnieuw gecompileerd te
worden:
#
cd /sys/modules/acpi/acpi && make clean && make ACPI_DEBUG=1
acpi.ko
moet in
/boot/kernel
komen te
staan en de gewenste debuglaag en het gewenste niveau van
uitvoerigheid dienen toegevoegd te worden aan
loader.conf
. Hieronder een voorbeeld
waarmee debuguitvoer wordt aangezet voor alle
ACPI-CA-componenten en alle
ACPI-hardware-stuurprogramma's
(CPU, LID, enzovoort.
Het niveau van uitvoerigheid is het laagst mogelijke. Er
worden alleen fouten gemeld.
debug.acpi.layer="ACPI_ALL_COMPONENTS ACPI_ALL_DRIVERS" debug.acpi.level="ACPI_LV_ERROR"
Als de gezochte informatie wordt veroorzaakt door een
specifieke gebeurtenis (bijvoorbeeld in en uit slaapstand gaan),
dan kunnen wijzigingen aan loader.conf
achterwege blijven en in plaats daarvan kan
sysctl
gebruikt worden om laag en niveau in
te stellen na het opstarten en zo het systeem voor te bereiden
op die specifieke gebeurtenis. De sysctl
s
hebben dezelfde namen als de parameters in
loader.conf
.
Meer informatie over ACPI staat op de volgende locaties:
De ACPI mailinglijst archieven http://lists.freebsd.org/pipermail/freebsd-acpi/
De oude ACPI mailinglijst archieven http://home.jp.FreeBSD.org/mail-list/acpi-jp/
De ACPI 2.0 specificatie
http://acpi.info/spec.htm
FreeBSD Handleidingen: acpi(4), acpi_thermal(4), acpidump(8), iasl(8), acpidb(8)
DSDT debugging informatie. (Gebruikt Compaq als voorbeeld, maar van algemeen nut).