- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个简单的程序试图访问用户空间中的物理内存,内核存储第一个结构页面。在 64 位机器上,这个地址是:
我试图通过用户空间的 mmap 访问这个物理地址。但是下面的代码会使内核崩溃。
int *addr;
if ((fd = open("/dev/mem", O_RDWR|O_SYNC)) < 0 ) {
printf("Error opening file. \n");
close(fd);
return (-1);
}
/* mmap. address of first struct page for 64 bit architectures
* is 0x0000620000000000.
*/
addr = (int *)mmap(0, num*STRUCT_PAGE_SIZE, PROT_READ, MAP_PRIVATE,
fd, 0x0000620000000000);
printf("addr: %p \n",addr);
printf("addr: %d \n",*addr); /* CRASH. */
最佳答案
我想我已经找到了问题——它与 x86 上的/dev/mem 内存映射保护有关。
请引用这篇 LWN 文章:“x86:使用配置选项引入/dev/mem 限制” http://lwn.net/Articles/267427/
CONFIG_NONPROMISC_DEVMEM
现在(我在最近的 3.2.21 内核上对此进行了测试),配置选项似乎被称为 CONFIG_STRICT_DEVMEM。
我更改了我的内核配置:
$ grep DEVMEM .config
# CONFIG_STRICT_DEVMEM is not set
$
当上面的 prg 使用 previous 内核运行时,设置了 CONFIG_STRICT_DEVMEM: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]
这是因为内核保护..
当内核被重建(使用 CONFIG_STRICT_DEVMEM UNSET)并且运行上面的 prg 时:
# ./a.out
mmap failed: Invalid argument
#
这是因为“offset”参数 > 1 MB(在 x86 上无效)(它是 16MB)。
使 mmap 偏移量在 1 MB 以内后:
# ./a.out
addr: 0xb7758000
*addr: 138293760
#
有效!有关详细信息,请参阅上面的 LWN 文章。
在支持 PAT(页面属性表)的 x86 架构上,内核仍然会阻止 DRAM 区域的映射。 kernel source中提到的原因是:
This check is nedded to avoid cache aliasing when PAT is enabled
此检查将导致与上述错误类似的错误。例如:
Program a.out tried to access /dev/mem between [mem 68200000-68201000].
可以通过禁用 PAT 来移除此限制。可以通过在启动时向内核命令行添加“nopat”参数来禁用 PAT。
关于c - 如何在不导致 Linux 内核崩溃的情况下访问 mmaped/dev/mem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11891979/
我是一名优秀的程序员,十分优秀!