linux - 如何从 Linux 中的用户空间访问物理地址?

标签 linux memory arm memory-address memory-mapping

在运行 Linux 的基于 ARM 的系统上,我有一个内存映射到物理地址的设备。从所有地址都是虚拟的用户空间程序中,我如何从该地址读取内容?

最佳答案

busybox devmem

busybox devmem 是一个用于映射 /dev/mem 的小型 CLI 实用程序。

你可以在 Ubuntu 中使用:sudo apt-get install busybox

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

sudo busybox devmem 0x12345678

0x9abcdef0 写入该地址:

sudo busybox devmem 0x12345678 w 0x9abcdef0

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

mmap MAP_SHARED

在映射 /dev/mem 时,您可能希望使用:

open("/dev/mem", O_RDWR | O_SYNC);
mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)

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

CONFIG_STRICT_DEVMEMnopat

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

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

没有这些,IO 端口仍然可以工作。

参见:mmap of /dev/mem fails with invalid argument for virt_to_phys address, but address is page aligned

缓存刷新

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

那么可能无法可靠地使用 /dev/mem 将内存缓冲区传递给设备?

很遗憾,这在 QEMU 中无法观察到,因为 QEMU 不模拟缓存。

如何测试它

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

  • Userland memory
    • 在用户态进程上分配 volatile 变量
    • 使用 /proc/<pid>/maps + /proc/<pid>/pagemap 获取物理地址
    • devmem 修改物理地址的值,观察用户态进程的 react
  • Kernelland memory
    • 使用 kmalloc 分配内核内存
    • 使用 virt_to_phys 获取物理地址并将其传回用户区
    • devmem修改物理地址
    • 从内核模块查询值
  • IO mem and QEMU virtual platform device
    • 创建具有已知物理寄存器地址的平台设备
    • 使用 devmem 写入寄存器
    • 观看 printf 响应从虚拟设备中出来

奖励:确定虚拟地址的物理地址

Is there any API for determining the physical address from virtual address in Linux?

关于linux - 如何从 Linux 中的用户空间访问物理地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12040303/

相关文章:

c++ - 我需要什么工具链来交叉编译 Clang for iOS

linux - Linux 上带有大矢量图像的 PDF 查看器?

c# - 哈希表 - 内存不足

embedded - 我的CPU不支持未对齐的内存访问是什么意思?

java - Windows 上的内存使用量不断增长

linux - 如何使用ramdisk减少嵌入式Linux中的 'Cached'内存

linux - arm hello world 未启动 - 命令对齐而不是页面对齐

linux - 使用 bash 命令删除除少数文件外的所有文件

linux - bash 脚本内 awk 命令中的括号不匹配导致语法错误

linux - 命令 "r--"命令的 UNIX Shell 脚本问题未找到