为啥 mmap /dev/mem 返回不同的地址?

     2023-02-17     99

关键词:

【中文标题】为啥 mmap /dev/mem 返回不同的地址?【英文标题】:Why mmap /dev/mem return different address?为什么 mmap /dev/mem 返回不同的地址? 【发布时间】:2014-02-18 04:41:36 【问题描述】:

这是程序:

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/file.h>
#include <errno.h>

long* mapmem(off_t offset)

    int fd;
    long *ret;

    fd = open("/dev/mem", O_RDWR|O_SYNC);

    if (fd == -1) 
        perror("open");
        return NULL;
    

    printf("offset (pageaddr) is: %ld\n", offset);

    ret = mmap(0, sizeof(long), PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
    if (ret == MAP_FAILED) 
        perror("mmap");
        ret = NULL;
    

    printf("Return address is: %p\n", ret);

    if (close(fd) == -1)
        perror("close");

    return ret;


int main(int argc, char *argv[])

    long *mem = 0;
    volatile long *_mem = 0, dummy;
    long long int addr, offset, pageaddr;
    char *endpt;

    if (argc != 2) 
        fprintf(stderr, "Usage %s <addr>\n", argv[0]);
        return 1;
    

    addr = strtoll(argv[1], &endpt, 16);
    offset = addr % sysconf(_SC_PAGE_SIZE);
    pageaddr = addr - offset;

    printf("addr is: %lld, offset: %lld, pageaddr: %lld\n", addr, offset, pageaddr);

    mem = mapmem(pageaddr);

    return 0;

为什么映射后的物理地址与我们传入的不同?还是返回的地址是映射到对应物理地址的虚拟地址?

我运行上述程序的输出:

 $ sudo ./test 0x12345
addr is: 74565, offset: 837, pageaddr: 73728
offset is: 73728
Return address is: 0x7f3081fc0000

【问题讨论】:

man mem: mem is a character device file that is an image of the main memory of the computer. 我猜这意味着您的程序要求操作系统将主内存的物理地址映射到进程虚拟空间中的某个地址。 为什么你认为虚拟地址应该和物理地址一样? @BasileStarynkevitch 我只是想确认返回的地址在我当前正在运行的程序的虚拟地址空间中,即使是从/dev/mem 映射的。我认为情况就是这样。对于普通地址,我知道它在虚拟地址空间中。 【参考方案1】:

Mmap 返回您可以访问的内存缓冲区的地址:因此,它是一个虚拟地址,也是因为物理地址应该对用户空间不可见。实际上,当前架构总是(但在启动过程的最初几秒内)在启用内存虚拟化的情况下运行。您只能在内核内部看到物理地址,并且只有当您明确使用物理内存时;但是您永远无法直接访问它们,您首先需要将它们映射到虚拟地址。

因此,您在程序中看到的是一个虚拟地址,它有时会有所不同。当您映射时,Linux 会在您的进程的虚拟内存中选择一个空闲的虚拟内存区域,该区域足够大以容纳您请求的映射,并将物理内存映射到该区域。 Linux 选择哪个虚拟内存区域取决于可用性和其他因素,例如地址空间布局随机化 (http://en.wikipedia.org/wiki/Address_space_layout_randomization)。

【讨论】:

/dev/mem和/dev/kmem的区别

...GPIO。用法一般就是open,然后mmap,接着可以使用map之后的地址来访问物理内存。这其实就是实现用户空间驱动的一种方法。/dev/kmem一般可以用来查看kernel的变量,或者用作rootkit之类的。 访问/dev/mem和/dev/kmem都需要root权限,... 查看详情

通过/dev/mem操作物理内存(代码片段)

...em",O_RDWR|O_SYNC);if(fd==-1)printf("failedtoopen/dev/mem!");return-1;base=mmap(NULL,sizeof(structtest_data),PROT_READ|PROT_WRITE,MAP_SHARED,fd,SRAM1_ADDR);if(base==MAP_FAILED)printf("failedtommap/dev/mem!");ret=-1;gotoerr_mmap;data=(structtest_data*)base;printf("datavalue:%x",data-> 查看详情

通过devmem访问物理地址(代码片段)

...层访问物理内存,发现应用层可以使用devmem工具访问物理地址。查看源码,实际上是对/dev/mem操作,通过mmap可以将物理地址映射到用户空间的虚拟地址上,在用户空间完成对设备寄存器的读写。藉由此原因,想深入理解下mmap的... 查看详情

如何将文件映射到内存?(代码片段)

...uffer设备文件)2、某些嵌入式设备,寄存器被编址到内存地址空间,我们可以映射/dev/mem某范围,去访问这些寄存器。3、如果多个进程映射同一个文件,还能实现进程通信的目的思路:使用标准库中的mmap模块中的mmap()函数,它... 查看详情

/dev/mem直接操作硬件寄存器

/********************************************************************************/dev/mem直接操作硬件寄存器*说明:*在和左栋讨论如何处理iomux的时候,可以直接通过操作/dev/mem进行iomux的pin映射。**2017-9-27深圳龙华樟坑村曾剑锋*************************** 查看详情

linux中ioremap和mmap的区别

...要用ioremap映射后,才能访问地址0xe8000000。这两个地址是不同的,mmu会帮你搞定,对你是透明的mmap在内核我用过ops中的mmap方法我写过一个例程,见附件。里面还有用户态的测试程序。本回答被提问者采纳 查看详情

如何正确处理 SIGBUS 以便我可以继续搜索地址?

】如何正确处理SIGBUS以便我可以继续搜索地址?【英文标题】:HowtocorrectlyhandleSIGBUSsoIcancontinuetosearchanaddress?【发布时间】:2018-05-3116:54:24【问题描述】:我目前正在处理一个项目,该项目在经过大量修改的Linux版本上运行,该版... 查看详情

为啥 mmap()(内存映射文件)比 read() 快

】为啥mmap()(内存映射文件)比read()快【英文标题】:Whymmap()(MemoryMappedFile)isfasterthanread()为什么mmap()(内存映射文件)比read()快【发布时间】:2015-05-2017:52:29【问题描述】:我最近正在研究JavaNIO的MappedByteBuffer。我读过一些关于... 查看详情

ws2811_initfailedwithcode-5(mmap()failed)错误解决方案(代码片段)

...n‘topen/dev/mem:PermissiondeniedRuntimeError:ws2811_initfailedwithcode-5(mmap()failed),看了网上好像没有什么解决办法,分享一个自己的在命令行下使用管理员权限运行程序获取root权限的方法#设置管理员密码(初始化时需要设置一次)sudopasswdroot#进... 查看详情

mmap 是不是连续分配堆内存?

...如果我在使用mmap在堆上分配内存时始终遵循这些规则,返回的地址会是连续的吗?或者他们之间会不会有差距?【问题讨论】:在哪个操作系统中?这些东 查看详情

mmap

...间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。 实际操作头文件<sys/mman.h> void*mmap(void*start,size_tlength,intprot,intflags,intfd,off_toffset);intmunmap(void*start,size_tlength);------------恢复内容结束------... 查看详情

为啥超过 255 的返回码在 C++ 中返回不同的数字?

】为啥超过255的返回码在C++中返回不同的数字?【英文标题】:Whydoreturncodesover255returnadifferntnumberinC++?为什么超过255的返回码在C++中返回不同的数字?【发布时间】:2016-01-2023:23:40【问题描述】:例如...#include<iostream>usingnames... 查看详情

为啥 MFCC 提取库返回不同的值?

】为啥MFCC提取库返回不同的值?【英文标题】:WhydoMFCCextractionlibsreturndifferentvalues?为什么MFCC提取库返回不同的值?【发布时间】:2019-02-0607:04:08【问题描述】:我正在使用两个不同的库提取MFCC特征:python_speech_features库BOB库但... 查看详情

为啥没有为不同的返回类型定义方法重载?

】为啥没有为不同的返回类型定义方法重载?【英文标题】:Whyismethodoverloadingnotdefinedfordifferentreturntypes?为什么没有为不同的返回类型定义方法重载?【发布时间】:2010-12-0715:29:55【问题描述】:在Scala中,您可以通过使方法共... 查看详情

为啥 GridSearchCV 返回的分数与直接运行模型返回的分数如此不同?

】为啥GridSearchCV返回的分数与直接运行模型返回的分数如此不同?【英文标题】:WhyGridSearchCVreturnscoresodifferentfromthescorereturnedbyrunningmodeldirectly?为什么GridSearchCV返回的分数与直接运行模型返回的分数如此不同?【发布时间】:2017... 查看详情

为啥 mmap 不能分配内存?

】为啥mmap不能分配内存?【英文标题】:Whymmapcannotallocatememory?为什么mmap不能分配内存?【发布时间】:2015-02-2209:46:04【问题描述】:我以root权限运行该程序,但它一直抱怨mmap无法分配内存。代码sn-p如下:#definePROTECTION(PROT_READ... 查看详情

linuxdump内存

...sWiki创建了dump文件core.2071曾经,Linux提供了两个虚拟设备/dev/mem和/dev/kmem用于dump内存,然而很多发行版基于安全因素没有开启。/dev/mem链接物理内存,/dev/kmem映射整个虚拟内存空间。后来的Linux内核,/dev/kmem不再使用。/dev/mem收到... 查看详情

Android:位置服务每次返回不同的数字 - 为啥?

】Android:位置服务每次返回不同的数字-为啥?【英文标题】:Android:locationservicereturnsdifferentnumberateachandeverytime-Why?Android:位置服务每次返回不同的数字-为什么?【发布时间】:2018-07-2100:26:22【问题描述】:您好,我正在开发一... 查看详情