gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-28 23:29:00 25 4
gpt4 key购买 nike

在运行 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com