Creo que he encontrado el problema - tiene que ver con/dev/mem de protección de mapeo de memoria en el x86.
Pl se refieren a este artículo LWN: "x86: introducir restricciones/dev/mem con una opción de configuración" http://lwn.net/Articles/267427/
CONFIG_NONPROMISC_DEVMEM
ahora (i probado esto en una reciente 3.2.21 del núcleo) , la opción de configuración parece llamarse CONFIG_STRICT_DEVMEM.
he cambiado de configuración del núcleo:
$ grep DEVMEM .config
# CONFIG_STRICT_DEVMEM is not set
$
Cuando el prg anterior se realizó con el kernel anterior, con CONFIG_STRICT_DEVMEM SET: muestra dmesg:
[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]
Esto se debe a la protección del núcleo ...
Cuando se reconstruyó el kernel (con CONFIG_STRICT_DEVMEM DESACTIVADO) y el PRG anteriormente se corrió:
# ./a.out
mmap failed: Invalid argument
#
Esto es debido a que el parámetro de 'compensar' es> 1 MB (no válidos en x86) (era de 16 MB).
Después de hacer el desplazamiento a estar dentro de 1 MB mmap:
# ./a.out
addr: 0xb7758000
*addr: 138293760
#
funciona! Vea el artículo anterior de LWN para más detalles.
En las arquitecturas x86 con soporte PAT (tabla de atributos de página), el kernel sigue evitando el mapeo de las regiones DRAM. La razón de esto como se menciona en el kernel source es:
This check is nedded to avoid cache aliasing when PAT is enabled
Esta verificación causará un error similar a la mencionada anteriormente. Por ejemplo:
Program a.out tried to access /dev/mem between [mem 68200000-68201000].
Esta restricción se puede eliminar inhabilitando PAT. PAT se puede desactivar agregando el argumento "nopat" a la línea de comandos del kernel en el momento del inicio.
¿Cuál es el valor que devuelve mmap() en addr? – BjoernD
@BjoernD: Intenté lo anterior en un x86 de 32 bits (reemplazando el desplazamiento de mmap como 0x01000000); addr = 0xffffffff. Y sí, se bloquea, por supuesto, en la desreferencia. ¿Cual es la solución? – kaiwan
0xffffffff == -1 -> mmap() está devolviendo un error. De acuerdo con la página man, el motivo del error se da en la variable 'errno'. Así que es posible que desee comprobar tat. – BjoernD