Archiv/acpi-fix

Archivierte Anleitung

Dieser Artikel wurde archiviert. Das bedeutet, dass er nicht mehr auf Richtigkeit überprüft oder anderweitig gepflegt wird. Der Inhalt wurde für keine aktuell unterstützte Ubuntu-Version getestet. Wenn du Gründe für eine Wiederherstellung siehst, melde dich bitte in der Diskussion zum Artikel. Bis dahin bleibt die Seite für weitere Änderungen gesperrt.

Achtung!

Ab Kernel 2.6.30 bzw. ab Ubuntu 9.10 lassen sich die DSDT-Tabellen nicht mehr zur Laufzeit überschreiben, da der entsprechende Kernel-Patch nicht mehr im Standardkernel vorhanden ist. Diese Anleitung funktioniert also nur bis einschließlich Ubuntu 9.04 Jaunty Jackalope.

Unter Ubuntu 10.04 muss man nun einen eigenen Kernel mit geänderter DSDT-Tabelle kompilieren. Eine Anleitung findet sich hier: DSDT-Fix FSC Amilo xi 1526 🇩🇪. Eine weitere Quelle: Patching DSDT in recent Linux kernels without recompiling 🇬🇧

Artikel für fortgeschrittene Anwender

Dieser Artikel erfordert mehr Erfahrung im Umgang mit Linux und ist daher nur für fortgeschrittene Benutzer gedacht.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

  1. Installation von Programmen

  2. Bearbeiten von Paketquellen

  3. Ein Terminal öffnen

  4. Einen Editor öffnen

Inhaltsverzeichnis
  1. Vorbereitung
  2. Kurzanleitung
  3. Typische Fehler in der dsdt
    1. Warning 1079 - ^ Reserved method must re...
    2. Error 1080 - Use of reserved word ^ (_T_...
    3. Warning 1103 - Possible operator timeou...
    4. Warning 1098 - Statement is unreachable
    5. _WDG und _WED
  4. Quellen

Viele Linuxnutzer, insbesondere die Gruppe der Notebookbenutzer, hat unter Linux Probleme mit ACPI. Dies äußert sich meist in der nicht richtig funktionierenden Speedstep/powernow-Drosselung der Taktfrequenz, falschen oder keinen Akkuangaben sowie nicht funktionierenden Suspend-Modi. Die Ursache liegt oft in der vom Hersteller fehlerhaft implementierten ACPI-Tabelle im BIOS. Hier wird jedes ACPI-Gerät sowie die Funktionen genau beschrieben. Die Beschreibung wurde im ACPI-Standard festgelegt. Leider werden diese Tabellen fast immer mit dem Microsoft Compiler übersetzt, welcher viele Fehler durchgehen lässt, da Windows hier nicht ganz standardkonform und sehr fehlertolerant arbeitet. Linux nimmt diese Fehler aber ernst und produziert meist Fehler. Glücklicherweise lassen sich diese sogenannten DSDT-Tabellen aber zur Bootzeit mit eigenen überschreiben. Der dazu notwendige Kernel-Patch 🇬🇧 ist bereits in den Ubuntu-Quellen und dem Standardkernel enthalten.

Nachfolgend eine Schritt-für-Schritt Anleitung, wer sich genauer mit dem Thema auseinander setzen möchte, findet am Ende weiterführende Links.

Vorbereitung

Zuerst muss der ASL Compiler von Intel installiert werden [1]:

Paketliste zum Kopieren:

sudo apt-get install iasl 

Oder mit apturl die Pakete installieren. Link: apt://iasl

Kurzanleitung

Im Terminal [3] liest

sudo cat /proc/acpi/dsdt > dsdt.dat 

die aktuell geladene DSDT Tabelle aus und schreibt sie in eine Datei.

Falls diese Datei/Verzeichnis nicht vorhanden ist, hilft das Programm "acpidump" aus den Paketquellen weiter. Installiert[1] wird dieses über das Paket:

Paketliste zum Kopieren:

sudo apt-get install acpidump 

Oder mit apturl die Pakete installieren. Link: apt://acpidump

Mit dem Befehl

sudo acpidump -t DSDT -o dsdt.dat -b 

kann man sich dann die DSDT Tabelle herausschreiben lassen. Dabei gibt -o den Ausgabepfad an und -b sorgt für eine binäre Ausgabe der Daten.

Mit dem Befehl

iasl -d dsdt.dat 

disassembliert man nun die Datei und erzeugt eine dsdt.dsl-Datei.

Diese Datei wiederum kompiliert man mit folgendem Befehl:

iasl -sa dsdt.dsl 

Dabei werden Fehler und Warnungen ausgegeben, die gefixt 🇬🇧 werden müssen. Bevor man es selber versucht, lohnt sich ein Blick auf ACPI4Linux 🇬🇧 , ob dort schon eine passende DSDT vorhanden ist.

Man fixt die Fehler im allgemeinen indem man die Datei dsdt.dsl mit einem Texteditor öffnet und die Verbesserungen vornimmt. Danach muss man sie wieder kompilieren (s.o.).

Nachdem es ohne Fehler kompiliert wurde, kann man die fehlerfreie DSDT.aml per initramfs-tools beim Booten an den Kernel übergeben. Zuerst kopiert man die Datei:

sudo cp dsdt.aml /etc/initramfs-tools/DSDT.aml 

und aktualisiert dann mit:

sudo update-initramfs -u 

Zum Schluss muss das System neu gestartet werden.

Nach einem Hardwarewechsel, wie z.B. dem Austausch der Hauptplatine bei einem Desktoprechner oder einem BIOS-Update muss die gefixte DSDT-Datei natürlich aus dem System entfernt werden, da diese nicht mehr mit der neuen Hardware bzw. der neuen BIOS-Version kompatibel ist und Fehler verursacht. Dazu wird die Datei DSDT.aml einfach gelöscht und aus dem Kernel entfernt:

sudo rm /etc/initramfs-tools/DSDT.aml
sudo update-initramfs -u 

Typische Fehler in der dsdt

Je nachdem welches Notebook man besitzt, gibt einem der Intel ASL Compiler unterschiedliche Fehlermeldungen und Warnungen zurück. Hier soll nun eine Auflistung von bekannten (oder weniger bekannten) Fehlern und Warnungen aufgelistet werden. Das ist praktisch, da so ein lästiges Zusammensuchen von Fixes im Internet entfällt und zum anderen auch nicht zu jedem Fehler ein Fix im Internet gefunden werden kann. Hier helfen meist nur E-Mails an Compiler-Autoren (wie z.B. an Robert Moore, der der Autor des Intel ASL Compiler ist) oder Sonstige.

Warning 1079 - ^ Reserved method must return a value (_WAK)

Dieser Fehler sollte durch Hinzufügen der nachfolgenden Codezeile vor der letzten geschweiften Klammer in betroffener Funktion behoben werden können.

Return(Package(0x02){0x00, 0x00}) 

Im Gesamtkontext sollte es in etwa so aussehen:

Method (\_WAK, 1, NotSerialized) 
    {
        SALD (0x00)
        Store (0xFF, DBG1)
        Store (0x00, SFLG)
        If (LEqual (RTCW, 0x00))
        {
            Notify (\_SB.PWRB, 0x02)
        }

        Notify (\_SB.PCI0.USB0, 0x00)
        If (LGreaterEqual (OSFL, 0x01))
        {
            Store (0x00, \_SB.PCI0.SMB0.SMPM)
        }
        Return(Package(0x02){0x00, 0x00})
    }

Error 1080 - Use of reserved word ^ (_T_0)

Manchmal erscheint dieser Fehler bei den Variablen _T_0, _T_1, _T_2 und _T_3. Wenn man sich die ACPI Spezifikation 3.0 unter acpi.info 🇬🇧 vornimmt, so findet man in der .pdf-Datei auf Seite 449 den Abschnitt "17.2.1.1 _T_x Reserved Object Names". Dort wird beschrieben, dass Wörter der Form _T_x bestimmte reservierte Wörter sind, die vom ASL Compiler selbst benutzt werden, um Zwischenwerte für komplizierte Berechnungen und Fallunterscheidungen zu speichern.

Dasselbe gibt der Compiler auch als Output am Ende aus, der Fehler ist also etwas paradox: der Compiler erkennt, dass es sich um bestimmte reservierte Wörter handelt (ist auch richtig so), markiert diese aber seltsamer Weise als Fehler. Die Lösung scheint einfach zu sein: einfach das Wort umbenennen. Unter der ACPI Spezifikation findet man unter anderem auf Seite 429 im Abschnitt "17.1.2 ASL Name and Pathname Terms" eine Erklärung über den Aufbau von Wörtern. Diese müssen von der Form "NameSeg" sein. Schaut man die Grammatik-Regeln genauer an, so erkennt man, dass es sich hierbei um Wörter handelt, die aus vier Buchstaben bestehen (mit Restriktionen bzgl. eines bestimmten Alphabets und bestimmten Zahlen). Auch _T_x hat eine ähnliche Form, gehört aber nicht zu dieser Wort-Klasse. Das ist aber egal, wichtig ist nur: der Compiler akzeptiert hier auch Wörter der Form 'NameSeg'.

Daher benennt man diese Wörter um: _T_0 -> dit0, ..., _T_3 -> dit3. Man kann sich natürlich auch jedes beliebige andere Wort einfallen lassen (blaa, blab, ... oder abcd, dcba, ...). Hauptsache die Restriktionen werden eingehalten.

Warning 1103 - Possible operator timeout is ignored

Eine mögliche Meldung kann lauten

dsdt.dsl  4244:                         Acquire (MUT0, 0x0FFF) 
Warning  1103 -        Possible operator timeout is ignored ^

Der Wert 0x0FFF oder jeder andere ist dabei in der betreffenden Zeile durch ein 0xFFFF zu ersetzen.

Warning 1098 - Statement is unreachable

Diese Warnung wird dann ausgegeben, wenn zwischen Return-Statement und schließender Klammer weitere Statements stehen; z.B.:

Method (PHS, 1, Serialized)
{
    Acquire (PSMX, 0xFFFF)
    Store (Arg0, BCMD)
    Store (Zero, SMIC)
    Store (Zero, BBCMD)
    Return (Inf)
    Release (PSMX)
}

Um diese Warnung zu beheben werden die letzen beiden Zeilen so vertauscht, dass erst das Release- und dann das Return-Statement stehen:

...
    Release (PSMX)
    Return (Inf)
}

_WDG und _WED

Das allgemeine Problem zwischen Linux und den ACPI Tabellen ist darauf zurückzuführen, dass es neben dem Compiler von Intel auch einen von Microsoft gibt, der sich nicht zu 100% an die ACPI-Spezifikationen hält. Die reservierten Wörter _WDG und _WED wurden von Microsoft nachträglich eingefügt, um damit auf einfache Weise ein internes Mapping von ACPI auf WMI durchführen zu können (Quelle?).

Fehler dieser Art können sehr leicht behoben werden: statt des Intel ALS Compilers Version 20051216 einfach einen aktuelleren ab Version 20061109 verwenden.

Nach einem Neustart sollte die neue Tabelle eingelesen werden.

Quellen