什么是/dev/mem?

47 memory linux dev

据推测它与内存有某种关系?什么会

sudo cat /dev/urandom > /dev/mem
Run Code Online (Sandbox Code Playgroud)

做?垃圾所有内存?所有非内核虚拟内存?以上都不是?

And*_*gan 36

它提供对系统物理内存的访问。

mem(4)手册页介绍了更多关于什么/dev/mem是。

是的 - 它可能会导致各种问题。重新启动应该可以解决您的问题,但是很容易发生不好的事情。当心!:-)

  • 我建议查看 mem 手册页。拉格是对的。“mem 是一个字符设备文件,它是计算机主内存的映像。例如,它可用于检查(甚至修补)系统。mem 中的字节地址被解释为物理内存地址。” 并且...“文件kmem 与mem 相同,只是访问的是内核虚拟内存而不是物理内存。” (4认同)

rag*_*ags 20

/dev/mem 提供对系统物理内存的访问,而不是虚拟内存。可以使用 /dev/kmem 访问内核虚拟地址空间。

它主要用于访问与外围硬件(如视频适配器)相关的 IO 内存地址。


Sah*_*ngh 10

sudo cat /dev/urandom > /dev/mem不会做任何事情,因为 sudo 会提升 cat 的特权,但不会提升重定向的特权。您可以sudo su在 root shell 中执行然后工作,或者使用
sudo dd if=/dev/urandom of=/dev/mem

/dev/mem提供对物理内存的访问,即系统中的所有 RAM,但这并不意味着它为您提供对 RAM 的完全读/写访问(请参阅文档中的CONFIG_STRICT_DEVMEM 选项)。另请注意,物理内存的某些区域会将其他设备(如视频卡内存等)映射到其上。

盲目写作/dev/mem会导致不确定的行为,这里有一个 youtube 视频也在做同样的事情。


Cir*_*郝海东 8

测试一下 busybox devmem

busybox devmem是一个用于 mmaps 的微型 CLI 实用程序/dev/mem

您可以通过以下方式在 Ubuntu 中获取它: sudo apt-get install busybox

用法:从物理地址读取 4 个字节0x12345678

sudo busybox devmem 0x12345678
Run Code Online (Sandbox Code Playgroud)

写信0x9abcdef0到那个地址:

sudo busybox devmem 0x12345678 w 0x9abcdef0
Run Code Online (Sandbox Code Playgroud)

来源:https : //github.com/mirror/busybox/blob/1_27_2/miscutils/devmem.c#L85

MAP_SHARED

在 mmapping 时/dev/mem,您可能想要使用:

open("/dev/mem", O_RDWR | O_SYNC);
mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)
Run Code Online (Sandbox Code Playgroud)

MAP_SHARED 使写入立即进入物理内存,这更容易观察,并且对硬件寄存器写入更有意义。

CONFIG_STRICT_DEVMEMnopat

要用于/dev/mem查看和修改内核 v4.9 上的常规 RAM,您必须先:

  • 禁用CONFIG_STRICT_DEVMEM(在 Ubuntu 17.04 上默认设置)
  • 传递nopatx86的内核命令行选项

IO 端口在没有这些的情况下仍然可以工作。

另见:https : //stackoverflow.com/questions/39134990/mmap-of-dev-mem-fails-with-invalid-argument-for-virt-to-phys-address-but-addre/45127582#45127582

缓存刷新

如果您尝试写入 RAM 而不是寄存器,则内存可能被 CPU 缓存:https : //stackoverflow.com/questions/22701352/how-to-flush-the-cpu-cache-for-a-region -of-address-space-in-linux并且我没有看到一种非常便携/简单的方法来刷新它或将区域标记为不可缓存:

那么也许/dev/mem不能可靠地用于将内存缓冲区传递给设备?

不幸的是,这在 QEMU 中无法观察到,因为 QEMU 不模拟缓存。

如何测试

现在是有趣的部分。这里有一些很酷的设置:

  • 用户空间内存
    • volatile在用户态进程上分配变量
    • 使用/proc/<pid>/maps+获取物理地址/proc/<pid>/pagemap
    • 物理地址devmem2,并观察用户进程的反应:
  • 内核内存
    • 分配内核内存 kmalloc
    • 获取物理地址virt_to_phys并将其传回用户空间
    • 修改物理地址 devmem2
    • 从内核模块查询值
  • IO mem 和 QEMU 虚拟平台设备
    • 创建具有已知物理寄存器地址的平台设备
    • 用于devmem2写入寄存器
    • watchprintf从虚拟设备中出来作为响应


plu*_*ash 5

/dev/mem 传统上提供对整个物理地址空间的访问。这包括 ram,但也包括任何内存映射的 IO 设备。

许多现代内核将配置为“CONFIG_STRICT_DEVMEM”,它将 /dev/mem 限制为仅内存映射 IO 设备。

向它随机写入垃圾是一个坏主意,但究竟会发生什么坏事是很难预测的。硬件可能会以不可预知的方式响应随机垃圾,损坏的内核内存结构可能会导致不可预知的内核行为。最好的情况是系统崩溃,最坏的情况是数据损坏甚至硬件变砖都不是问题。

PS 请注意,您的命令在以普通用户身份运行时不应执行任何操作,因为 sudo 仅提升 cat 命令,而不是重定向。