Ich denke, ich habe das Problem gefunden - es ist mit/Dev/Mem Memory Mapping-Schutz auf dem x86 zu tun.
Pl beziehen sich auf diese LWN Artikel: "x86: Einführung/dev/mem Einschränkungen mit einer Konfigurationsoption" http://lwn.net/Articles/267427/
CONFIG_NONPROMISC_DEVMEM
Now (Getestet habe ich diese auf einem aktuellen 3.2.21 Kernel) scheint die Konfigurationsoption CONFIG_STRICT_DEVMEM zu heißen.
ich meine Kernel-Konfiguration geändert:
$ grep DEVMEM .config
# CONFIG_STRICT_DEVMEM is not set
$
Wenn die oben prg mit dem vorherigen Kernel ausgeführt wurde, mit CONFIG_STRICT_DEVMEM SET: dmesg zeigt:
[29537.565599] Program a.out tried to access /dev/mem between 1000000->1001000.
[29537.565663] a.out[13575]: segfault at ffffffff ip 080485bd sp bfb8d640 error 4 in a.out[8048000+1000]
Dies wegen der ist Kernelschutz ..
Wenn der Kernel neu erstellt wurde (mit dem CONFIG_STRICT_DEVMEM UNSET) und die oben prg ausgeführt wurde:
# ./a.out
mmap failed: Invalid argument
#
Dies liegt daran, die 'Offset' Parameter> 1 MB (ungültig auf x86) (es war 16MB).
Nach dem Mmap machen Offset innerhalb von 1 MB sein:
# ./a.out
addr: 0xb7758000
*addr: 138293760
#
Es funktioniert! Siehe den obigen LWN Artikel für Details.
Auf x86-Architekturen mit PAT-Unterstützung (Page Attribute Table) verhindert der Kernel weiterhin die Zuordnung von DRAM-Bereichen. Der Grund dafür, wie in den kernel source erwähnt ist:
This check is nedded to avoid cache aliasing when PAT is enabled
Diese Prüfung einen ähnlichen Fehler, der die oben erwähnte verursachen. Beispiel:
Program a.out tried to access /dev/mem between [mem 68200000-68201000].
Diese Einschränkung kann durch Deaktivieren von PAT aufgehoben werden. PAT kann deaktiviert werden, indem das "nopat" -Argument während der Boot-Zeit zur Kernel-Befehlszeile hinzugefügt wird.
Was ist der Wert, den mmap() in addr zurückgibt? – BjoernD
@BjoernD: Ich habe das oben auf einem 32-Bit x86 (ersetzt mmap Offset als 0x01000000) versucht; addr = 0xffffffff. Und ja, es stürzt natürlich auf die Dereferenzierung ab. Was ist die Lösung? – kaiwan
0xffffffff == -1 -> mmap() gibt einen Fehler zurück. Laut der man-Seite wird der Grund für den Fehler in der Variablen 'errno' angegeben. Vielleicht möchtest du es also überprüfen. – BjoernD