Ati RAM MTRR
Diverse BIOSe übergeben dem Linux-Kernel die Arbeitspeicher-Daten inkorrekt. Das kann dazu führen, dass die MTRR-Register (Memory Type Range Registers) falsch gesetzt werden. Diese Register kontrollieren den den Zugriff auf Speicherbereiche (wichtig für Grafikkarten).
Asus A4K
1280 MB RAM; 2.6.17-2-amd64 Kernel; 8.28.8 fglrx-driver, fglrx-kernel-source, usw. via apt-get installiert. Mit dem module-assistant das fglrx Kernel-Module erstellt.
Nachdem ich mein Notebook von 512 MB auf 1280 MB RAM aufgerüstet hatte, funktionierten die Ati-Treiber nicht mehr.
Dank Google und einer grossen Portion Geduld fand ich heraus, dass das A4K anscheinend ein bescheidenes BIOS hat und die RAM-Angaben dem MTRR falsch übergeben werden. Etliche Fehlermeldungen wie :
[fglrx] Maximum main memory to use for locked dma buffers: 1126 MBytes. [fglrx] module loaded - fglrx 8.26.18 [Jun 22 2006] on minor 0 ... mtrr: no more MTRRs available [fglrx:firegl_addmap] *ERROR* mtrr allocation failed (-28) [fglrx] Internal AGP support requested, but kernel AGP support active. [fglrx] Have to use kernel AGP support to avoid conflicts. [fglrx] AGP detected, AgpState = 0x1f00421b (hardware caps of chipset) mtrr: no more MTRRs available [fglrx:firegl_unlock] *ERROR* Process 4265 using kernel context 0
wiesen mich darauf hin.
Nach dem Aufstarten sahen meine MTRR-Register wie folgt aus (mit xterm gemacht):
jonas@asusONE:~$ cat /proc/mtrr reg00: base=0x00000000 ( 0MB), size= 16MB: write-back, count=1 reg01: base=0x01000000 ( 16MB), size= 16MB: write-back, count=1 reg02: base=0x02000000 ( 32MB), size= 32MB: write-back, count=1 reg03: base=0x04000000 ( 64MB), size= 64MB: write-back, count=1 reg04: base=0x08000000 ( 128MB), size= 128MB: write-back, count=1 reg05: base=0x10000000 ( 256MB), size= 256MB: write-back, count=1 reg06: base=0x20000000 ( 512MB), size= 512MB: write-back, count=1 reg07: base=0x40000000 (1024MB), size=1024MB: write-back, count=1
Vom Recherchieren her weiss ich, dass bei anderen die Ausgabe nicht gleich aussieht. Teilweise ist nur ein Register besetzt, dafür dies mit TeraBytes...
Eigentlich sollte da irgendwo die Angaben des RAM von der Grafikkarte und des AGP stehen. Diese Angaben werden im Normalfall vom X-Server gesetzt. Aber da MTRR anscheinend maximal acht Register hat, ging das natürlich nicht mehr. Also in die Konsole wechseln und alle möglichen Grafikmodule entladen (radeon, drm, fglrx, agpgart, usw.) (als root).
rmmod radeon rmmod drm rmmod fglrx rmmod agpgart ...
Jetzt sollte man nochmals überprüfen, wie viele Register besetzt sind. In meinem Falle waren es immer noch sieben.
Dann müssen die MTRR-Register geleert werden (als root):
asusONE:/home/jonas# for i in 1 0 2 3 4 5 6 7; do echo "disable=$i" >| /proc/mtrr; done
Falls weniger Register besetzt sind, kann man mit einem echo "disable=REGISTERNR" >| /proc/mtrr die einzelnen Register löschen.
Ein cat /proc/mtrr sollte jetzt nichts mehr anzeigen.
Jetzt muss man den gesamten Arbeitspeicher dem MTRR-Register zuweisen. Dazu muss man die RAM angaben im Hexadezimalen Format kennen.
0x00000000 0MB 0x01000000 16MB 0x02000000 32MB 0x04000000 64MB 0x08000000 128MB 0x10000000 256MB 0x20000000 512MB 0x40000000 1024MB 0x60000000 1536MB 0x80000000 2048MB usw.
Mit einem (als root)
asusONE:/home/jonas# echo "base=0x00000000 size=0x40000000 type=write-back" >| /proc/mtrr
fügt man den Arbeitsspeicher dem MTRR hinzu. In diesem Falle sind es 1 GB RAM. Die Grösse size= muss natürlich individuell gewählt werden. Der Rest bleibt unverändert.
In meinem Falle war es nicht möglich, 1280 MB RAM (HEX: 0x50000000) als ein einzelnes Register in MTRR zu schreiben (anscheinend funktioniert es mit "ungeradem" Arbeitsspeicher nicht [1 und 2 ausgenommen]), darum habe ich es aufgeteilt :
asusONE:/home/jonas# echo "base=0x00000000 size=0x40000000 type=write-back" >| /proc/mtrr asusONE:/home/jonas# echo "base=0x40000000 size=0x10000000 type=write-back" >| /proc/mtrr
Mein MTRR zeigt nun folgendes an :
asusONE:/home/jonas# cat /proc/mtrr reg00: base=0x00000000 ( 0MB), size=1024MB: write-back, count=1 reg01: base=0x40000000 (1024MB), size= 256MB: write-back, count=1
So nun mal modprobe fglrx ausgeführt und das X-Window-System gestartet. Dann in einem xterm ein cat /proc/mtrr gemacht und siehe da :
asusONE:/home/jonas# cat /proc/mtrr reg00: base=0x00000000 ( 0MB), size=1024MB: write-back, count=1 reg01: base=0x40000000 (1024MB), size= 256MB: write-back, count=1 reg02: base=0xe0000000 (3584MB), size= 64MB: write-combining, count=1 reg03: base=0xf0000000 (3840MB), size= 128MB: write-combining, count=1
Die 64 MB sind der Speicher der Grafikkarte und die 128 MB der AGP Speicher. HEUREKA! OpenGL funktioniert wieder und das ganze System läuft viel flüssiger!
Damit ich das nicht bei jedem Start manuell ändern muss, habe ich folgende Zeile in meine /etc/rc.local vor dem exit 0 hinzugefügt :
# Disable the reg0x for i in 1 2 3 4 5 0 6 7; do echo "disable=$i" >| /proc/mtrr; done # RAM echo "base=0x00000000 size=0x40000000 type=write-back" >| /proc/mtrr echo "base=0x40000000 size=0x10000000 type=write-back" >| /proc/mtrr
Et voilà, das war's dann auch schon!
Ich übernehme keine Haftung für Schäden, die durch Anwendung obiger Angaben entstehen oder entstanden sind!