在 Linux 中将物理地址转换为虚拟地址并读取其内容
Posted
技术标签:
【中文标题】在 Linux 中将物理地址转换为虚拟地址并读取其内容【英文标题】:Convert physical address to virtual in Linux and read its content 【发布时间】:2013-10-29 23:05:49 【问题描述】:我有 Linux,我有一个物理地址:(即 0x60000000)。 我想从用户空间 Linux 程序中读取这个地址。
这个地址可能在内核空间。
【问题讨论】:
您可以使用mmap(2)
,如下所述:***.com/questions/12040303/…
Is there any API for determining the physical address from virtual address in Linux的可能重复
你的系统上有/dev/mem
吗?你有devmem
程序(检查type devmem
)吗?如果是这样,devmem 0x60000000
是否有效?如果是这样,编写一个 mmaps
的一部分 /dev/mem
的函数不是什么大问题,我有一个现成的代码。
在某些系统上还有devmem2
:manpages.ubuntu.com/manpages/xenial/man1/devmem2.1.html
【参考方案1】:
您需要一个内核驱动程序来将物理地址导出到用户级。
看看这个驱动:https://github.com/claudioscordino/mmap_alloc/blob/master/mmap_alloc.c
【讨论】:
【参考方案2】:请注意,现在可以通过 /proc/[pid]/pagemap 实现这一点
【讨论】:
你能扩展你的答案吗?它包含二进制数据。如何使用此文件?【参考方案3】:Is there an easy way I can do that?
对于从用户空间访问,mmap()
是一个不错的解决方案。
Is it possible to convert it by using some function like "phys_to_virt()"?
可以使用ioremap_nocache() 将物理地址映射到虚拟地址。但是从用户空间,你不能直接访问它。假设您的驱动程序或内核模块想要访问该物理地址,这是最好的方法。通常内存映射设备驱动程序使用此函数将寄存器映射到虚拟内存。
【讨论】:
赏金现在可用...另一个问题询问如何访问某些设备的寄存器的物理地址。这显然将驻留在内核内存中。是否可以将其转换为虚拟地址,然后将其提供给具有 4 个字节的copy_to_user()
函数以获取该寄存器的值?
这似乎是devmem
的工作。请参阅我在问题下的评论。【参考方案4】:
在 C 中类似这样。如果您轮询硬件寄存器,请确保添加 volatile 声明,以便编译器不会优化您的变量。
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <memory.h>
volatile int *hw_mmap = NULL; /*evil global variable method*/
int map_it()
/* open /dev/mem and error checking */
int i;
int file_handle = open(memDevice, O_RDWR | O_SYNC);
if (file_handle < 0)
DBG_PRINT("Failed to open /dev/mem: %s !\n",strerror(errno));
return errno;
/* mmap() the opened /dev/mem */
hw_mmap = (int *) (mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, file_handle, 0x60000000));
if(hw_mmap ==(void*) -1)
fprintf(stderr,"map_it: Cannot map memory into user space.\n");
return errno;
return 0;
现在您可以对 hw_mmap 进行读写操作了。
【讨论】:
以上是关于在 Linux 中将物理地址转换为虚拟地址并读取其内容的主要内容,如果未能解决你的问题,请参考以下文章