如何在不导致 Linux 内核崩溃的情况下访问 mmaped /dev/mem?

2024-10-30 08:35:00
admin
原创
171
摘要:问题描述:我有一个简单的程序,它尝试访问用户空间中的物理内存,内核在其中存储第一个 struct page。在 64 位机器上,此地址为:内核虚拟地址:ffffea0000000000物理地址:0000620000000000我尝试在用户空间通过 mmap 访问该物理地址。但以下代码导致内核崩溃。int *a...

问题描述:

我有一个简单的程序,它尝试访问用户空间中的物理内存,内核在其中存储第一个 struct page。在 64 位机器上,此地址为:

  • 内核虚拟地址:ffffea0000000000

  • 物理地址:0000620000000000

我尝试在用户空间通过 mmap 访问该物理地址。但以下代码导致内核崩溃。

int *addr;
if ((fd = open("/dev/mem", O_RDWR|O_SYNC)) < 0 ) {
    printf("Error opening file. 
");
    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 
",addr);
printf("addr: %d 
",*addr); /* CRASH. */

解决方案 1:

我想我已经找到了这个问题——它与 x86 上的 /dev/mem 内存映射保护有关。

请参阅此 LWN 文章:“x86:通过配置选项引入 /dev/mem 限制”
http://lwn.net/Articles/267427/

配置_NONPROMISC_DEVMEM

现在(我在最近的 3.2.21 内核上测试了这一点),配置选项似乎被称为 CONFIG_STRICT_DEVMEM。

我改变了我的内核配置:

$ grep DEVMEM .config
# CONFIG_STRICT_DEVMEM is not set
$ 

当使用以前的内核运行上述 prg 时,使用 CONFIG_STRICT_DEVMEM SET: 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 区域的映射。内核源代码中提到了这样做的原因是:

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。

解决方案 2:

在具有 PAT(页面属性表)支持的 x86 架构上,内核可以阻止 DRAM 区域的映射(即使在没有设置 CONFIG_NONPROMISC_DEVMEM 的情况下进行编译)。

内核源码中提到了这个问题的原因是:

This check is nedded to avoid cache aliasing when PAT is enabled

此检查将导致出现与dmesg上述 kaiwan 的回答中提到的类似错误。例如:

Program a.out tried to access /dev/mem between [mem 68200000-68201000].

可以通过禁用 PAT 来消除此限制。

nopat可以通过在启动时向内核命令行添加参数来禁用 PAT 。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1284  
  制作手机版 Minecraft(简称 mc)服务器,对于广大 mc 爱好者而言,是一件充满乐趣且富有挑战的事情。它不仅能让玩家们自由创建属于自己的游戏世界,还能与好友一同在这个独特的虚拟空间中尽情探索、建造和冒险。接下来,我们就详细探讨一下如何制作手机版 mc 服务器。前期准备工作在开始制作手机版 mc 服务器之前,有...
服务器端   0  
  微信作为一款广泛使用的社交软件,在人们的日常生活和工作中扮演着重要角色。而在一些特定场景下,需要实现微信上定点服务器登录,这对于保障信息安全、满足特定业务需求等方面有着重要意义。接下来,我们将深入探讨如何实现微信上定点服务器登录。理解微信登录机制微信的登录机制是一个复杂且严谨的体系。它首先通过用户输入的账号和密码进行身...
  0  
  树莓派作为一款小巧且功能强大的单板计算机,在众多领域都有着广泛的应用。搭建树莓派集群服务器,能够实现更强大的计算能力和数据处理能力,满足诸如小型数据中心、分布式计算等场景的需求。接下来,我们将详细探讨如何搭建树莓派集群服务器。前期准备在开始搭建树莓派集群服务器之前,充分的前期准备工作至关重要。首先是硬件方面,需要准备多...
  0  
  了解亚马逊云与 ECS 服务器在云计算领域,亚马逊云服务(AWS)占据着重要地位。它提供了广泛的云计算服务,满足不同用户的多样化需求。而 ECS(Elastic Compute Service)服务器作为其中关键的一项服务,为用户提供了可弹性扩展的计算能力。对于许多开发者、企业和创业者来说,开通并利用好亚马逊云的 EC...
  0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用