Kategorien
Ohne Kategorie

Mainboard-Sensoren für Gigabyte AB350-Gaming

Selbst mit einem aktuellen Linux-Kernel fehlen die Sensorwerte auf dem Gigabyte AB350-Gaming Mainboard (Sockel AM4). Eine Ausgabe von „sensors“ zeigt keinen der verbauten Hardwaresensoren an, die man im BIOS-Menü sehr wohl einsehen kann. Typischerweise hilft ein Aufruf von „sensors-detect“, um nach fehlenden Treibern zu suchen, und siehe da: Es findet tatsächlich zwei Super-I/O Chips.

Driver `to-be-written':
  * ISA bus, address 0xa40
    Chip `ITE IT8686E Super IO Sensors' (confidence: 9)

Driver `it87':
  * ISA bus, address 0xa60
    Chip `ITE IT8792E Super IO Sensors' (confidence: 9)

Allerdings gibt es offensichtlich keinen Treiber für den Ersten der Beiden. Hilfreich war dabei die Info von einem Github Gist, die einen Workaround aufzeigt. In Kurzform war folgendes nötig:

  1. Installiere den modifizierten it87-Treiber von https://github.com/gamanakis/it87.git, am besten via DKMS
  2. Erstelle die Datei /etc/modprobe.d/gigabyte-b350.conf mit dem Inhalt
    options it87 ignore_resource_conflict=1
  3. Lade das Modul beim Systemstart
  4. Korrigiere die Ausgabe von „sensors“. Dazu lege die Datei /etc/sensors.d/gigabyte-b350.conf an und fülle sie mit dem Inhalt, den Nutzer konomikitten hier vorgeschlagen hat: https://github.com/lm-sensors/lm-sensors/issues/137#issue-371641346

Kategorien
Ohne Kategorie

Störrische Nvidia-Grafik im Laptop: Treiber- oder Hardwareproblem?

Kürzlich versuchte ich die Nvidia-Grafikkarte eines älteren Laptops unter Linux zum Laufen zu bekommen. Betrieben wurde dieser ursprünglich mit Windows 8.1, doch dort kam es bereits zu Problemen. Witcher 3 beispielsweise lief damit nur mit fps-Werten nahe der eins, egal welche Einstellungen gewählt wurden. Weder Prozessor noch Arbeitsspeicher waren stark ausgelastet, also musste etwas anderes faul sein. Daher habe ich mal ein Linux auf das Gerät geworfen, um die Leistung damit zu testen.

Für das Modell (GeForce GT 630M) gibt es unter Linux zwei Treiber: Der proprietäre Treiber von Nvidia selbst oder der quelloffene nouveau-Treiber. Ersterer unterstützt die Grafikkarte des Laptops aber nur bis zur Version 390. Damit kann die Karte zwar grundsätzlich betrieben werden und bietet sogar nach eigener Angabe OpenGL 4.6 Unterstützung. Allerdings ist PRIME Render Offload erst aber Treiberversion 435 möglich, was bedeutet, dass Nvidia Optimus nur sehr rudimentär umgesetzt ist. Der freie nouveau-Treiber kann das dagegen schon länger. Dieser wiederum offeriert nur OpenGL 4.3 und auch eine etwas schlechtere 3D-Leistung.

Wenn der dedizierte Grafikchip nicht in Benutzung ist, soll er sich dann auch Schlafen legen. Das spart Akku und reduziert die Abwärme, im Falle des untersuchten Laptops senkt das die Temperatur am Lüfter bei ruhendem Desktop um ganze 15°C! Auch das sollte mit nouveau automatisch geschehen dank vga_switcheroo, doch geklappt hat das nicht. Ich vermutete, dass das Laptopmodell schlicht irgendwo inkompatibel ist oder eine fehlerhafte ACPI-Implementierung hat. Testweise habe ich dann bbswitch probiert, und das hat geklappt: Damit lässt sich die GPU aus- und wieder einschalten, wenn auch nur händisch.

Dabei kam aber ein interessantes Phänomen zum Vorschein: Nach dem Wiederanschalten waren beide Treiber nicht mehr in der Lage, die Grafikkarte erneut anzusprechen. nouveau erkannte das Modell nicht mehr und meldete einen unbekannten Chip mit der Nummer „0xffffffff“:

nouveau 0000:01:00.0: unknown chipset (ffffffff)

Hier war klar etwas schief gelaufen mit der Kommunikation, und die Ausgabe des proprietären Nvidia-Treibers schaffte etwas mehr Klarheit:

NVRM: GPU at 0000:01:00.0 has fallen off the bus.

Offenbar hatte sich die GPU von der PCIe-Schnittstelle verabschiedet, obwohl sie im eingeschalteten Zustand fröhlich weiter Energie verbrat. Einen Neustart später hatte sie sich zwar wieder beruhigt, doch das obige Problem war reproduzierbar. Für einen Wechsel zwischen Nvidia- und Intel-Grafik war so ein vollständiger Systemneustart nötig – und zu allem Überfluss war die 3D-Leistung der Nvidia-Grafik auch unter Linux nur marginal besser als die Intel-Grafik, was der Erfahrung mit Windows entspricht.

Einige Neustarts später kam dann die Erkenntnis: Die Hardware ist defekt. Denn plötzlich taucht die Nvidia-GPU gar nicht mehr auf! Sie wird vom PCI-Bus schlicht nicht mehr erkannt, entsprechend melden die Treiber, sie fänden keine Nvidia-Grafik im System. Auch habe ich das Gerät länger ohne Akku liegen lassen, doch das hat die Grafikkarte nicht wiederbelebt. Mein Stresstest hat ihr leider den Todesstoß versetzt.

Kategorien
Ohne Kategorie

Mit CMake + MinGW Windows-Ressourcen in die .exe bauen

Für den Bau einer Windows DLL oder EXE ist es meistens erforderlich, eine Ressourcendatei (.rc) zu integrieren. In dieser gibt man beispielsweise Versionsinformationen an oder versieht eine Anwendung mit einem Icon. Dazu übersetzt man die .rc-Datei mit dem Programm windres in eine Objektdatei und linkt diese in die ausführbare Datei.

CMake übernimmt diese Aufgabe automatisch, man muss lediglich die .rc-Datei als Quelldatei mit angeben:

add_executable(App main.c icon.rc version.rc)

So zumindest in der Theorie. So ganz automatisch ging das dann doch nicht, zumindest nicht bei mir. Zuerst musste ich CMake mitteilen, dass es die .rc-Dateien übersetzen soll:

enable_language(RC)

Damit funktioniert das ganze schon mal mit dem Microsoft-Compiler und dessen windres. Auch MinGW bringt den windres-Compiler mit, allerdings mit anderen Aufrufparametern. Daher schlug die Übersetzung der .rc-Dateien fehl. Um CMake den korrekten Aufruf mitzuteilen, war ein weiterer Befehl nötig:

if (${MINGW})
    SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
endif()

Eigentlich sollte CMake seit Version 2.8.7 auch mit MinGW-windres zusammenarbeiten, zumindest laut dem TigerVNC-Projekt. Trotz der von mir verwendeten Version 3.12 hatte ich jedoch nur mit obigem Workaround Erfolg.

Kategorien
Ohne Kategorie

Qt5 Anwendung mit MinGW 9 übersetzen

Versucht man eine Qt5 Anwendung mit MinGW-W64 zu übersetzen, stößt man sehr wahrscheinlich auf folgendes Problem:

In file included from /usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/include/c++/bits/stl_algo.h:59,
                 from /usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/include/c++/algorithm:62,
                 from /opt/Qt5/include/QtCore/qglobal.h:142,
                 ...

/usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/include/c++/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
   75 | #include_next <stdlib.h>
      |               ^~~~~~~~~~
compilation terminated.

Hilfreich dabei war ein Blog-Eintrag von ocroquette: Die Fehlerursache liegt in den System-Includepfaden, die man gcc mit dem -isystem Schalter mitteilt. Leider fügt Qt5 seine eigenen Headerdateien selbst als System-Include hinzu und sorgt dadurch dafür, dass der Standard-Includepfad von MinGW32 nicht mehr von den Qt5 Headerdateien beachtet wird. Zur Lösung muss man diesen manuell hinzufügen, beispielsweise in CMake:

if (${MINGW})
    list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES /usr/x86_64-w64-mingw32/include)
endif()

Dieser Codeschnipsel sollte am besten nach dem Importieren von Qt5 und vor dem Definieren eigener Targets einfügen.

Nachtrag vom 14.10.2020:

Mit Qt 5.14 kommt ein weiteres Problem hinzu, hier kommt der Fehler schon beim importieren von Qt5::Core zum Vorschein, jedoch findet MinGW diesmal seine Standardbibliotheken nicht mehr:

CMake Error at /opt/Qt5/lib/cmake/Qt5Core/Qt5CoreConfig.cmake:92 (message):
    Library not found: mpr
Call Stack (most recent call first):
    /opt/Qt5/lib/cmake/Qt5Core/Qt5CoreConfig.cmake:272 (_qt5_Core_process_prl_file)
  /opt/Qt5/lib/cmake/Qt5/Qt5Config.cmake:28 (find_package)
  CMakeLists.txt:13 (find_package)

Auch hier bringt Qt5 wohl den Standardincludepfad durcheinander, und der Fix ist sehr ähnlich wie oben:

if (${MINGW})
    list(APPEND CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES /usr/x86_64-w64-mingw32/lib)
endif()
Kategorien
Ohne Kategorie

Kombo-Klinkenbuchse unter Linux nutzbar machen

Bei heutigen Notebooks findet man in aller Regel nur noch eine einzige Klinkenbuchse zum Anschluss eines Kopfhörers oder Headsets. Diese ist dabei als sogenannte Kombobuchse ausgeführt, da sie je nach eingestecktem Medium entweder als Kopfhörer-, Headset- oder Mikrofonbuchse wirken kann. Solche Buchsen sind baulich wie die Kopfhörerbuchsen bei Smartphones aufgebaut, das heißt vierpolig. Ein passender Stecker von einem Headset z.B. sieht dann wie folgt aus, wobei AUX der Mikrofonkontakt ist:

Darstellung eines vierpoligen Klinkensteckers. Von der Spitze Richtung Schaft: Audio links, Audio rechts, Masse, Mikrofon
Vierpoliger Klinkenstecker ©2013 Martin Meise CC BY-SA 3.0

Unter Linux funktionieren diese Buchsen teilweise nicht wie vorgesehen, da die Treiberunterstützung bei manchen Notebookmodellen nicht ausreichend vorhanden ist. Im Falle meines eigenen Notebooks (ASUS X751LK) funktionierte bei einem eingesteckten Headset nur der Kopfhörer, aber nicht das Mikrofon. ALSA hatte weiterhin das eingebaute Mikro benutzt und nicht erkannt, dass ein Headset angeschlossen war.

Mikrofon mit hdajackretask aktivieren

Die Lösung dazu war das Programm hdajackretask, welches den Ein- und Ausgängen der Soundkarte eine neue Funktion „aufzwingen“ kann. Im Falle meines Notebooks hat sich nämlich herausgestellt, dass der Kontakt für das Mikrofon in der Buchse als separater Eingang an der internen Soundkarte angebunden ist, allerdings standardmäßig nicht aktiv ist. Um den Treiber zu überreden, den Eingang doch zu nutzen, musste ich ein „Override“ für den Kontakt einrichten, was wie folgt ging:

  1. Ich wähle die passende Soundkarte aus. In meinem Fall steht „Intel Haswell HDMI“ und „Realtek ALC3236“ zur Auswahl. Ersterer ist nur für HDMI-Audio zuständig, ich wähle also den Realtek-Chip.
Auswahl der Soundkarte
  1. Meistens hilft es, „Set model=auto“ zu wählen, in meinem Fall macht das aber keinen Unterschied. Bei den angezeigten Kontakten ist auch keiner für ein externes Mikrofon dabei. Daher lasse ich mir mit „Show unconnected pins“ die laut Treiber nicht angeschlossenen Kontakte anzeigen.
Wählen von model=auto und unconnected pins
  1. Ich probiere also die Kontakte durch, wähle jeweils den Haken bei „Override“ an und stelle auf „Microphone“. Ein Klick auf „Apply now“ erlaubt mir einen Test damit. Bei Kontakt 0x19 habe ich Glück: Bei angeschlossenem Headset kommt darüber tatsächlich das Mikrofonsignal!
Aktivieren eines Overrides
  1. Ich führe zur Sicherheit einen Reboot durch und teste erneut. Da es immer noch klappt, aktiviere ich mit „Install boot override“ diese Konfiguration fest für jeden Systemstart.