/ dev / mem上的mmap CMA区域

时间:2014-01-21 11:13:09

标签: linux mmap

我需要保留256-512 Mb的连续物理内存,并且可以从用户空间访问此内存  我决定使用CMA进行记忆保存 以下是我必须执行的想法的步骤:

  1. 在系统启动期间由CMA预留所需的内存量。
  2. 解析CMA补丁输出,例如:“CMA:在27400000保留256 MiB”并保存两个参数:CMA区域的大小= 256 * 1024 * 1024字节和CMA区域的物理地址= 0x27400000。
  3. 使用mmap()在/ dev / mem文件中使用offset = 0x27400000映射CMA区域。 (当然,CONFIG_STRICT_DEVMEM被禁用) 它允许我直接从用户空间的phys内存中读取数据。
  4. 但是下一个代码会导致分段错误(大小= 1Mb):

    int file;
    void* start;
    
    file=open("/dev/mem", O_RDWR | O_SYNC);
    
    if ( (start = mmap(0, 1024*1024, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0x27400000)) == MAP_FAILED ){
        perror("mmap");
    }
    
    for (int offs = 0; offs<50; offs++){
        cout<<((char *)start)[offs];
    }
    

    此代码的输出:“mmap:无效的参数”。

    当我在0上更改offset = 0x27400000时,此代码工作正常并且程序显示为垃圾。它也适用于我看过/ proc / iomem的很多偏移。 根据来自/ proc / iomem的信息,CMA区域的phys addr(我系统上的0x27400000)总是位于系统RAM中。

    有没有人有任何想法,如何在/ dev / mem上映射CMA区域?我究竟做错了什么? 非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

Jeff Haran在kernelnewbies邮件列表中向我建议了解决这个问题的方法 有必要在.config中禁用CONFIG_x86_PAT并且mmap()已经开始工作了!

  

如果配置了CONFIG_X86_PAT,则在将内存映射到用户空间时会遇到问题。它基本上实现了与CONFIG_STRICT_DEVMEM相同的限制   杰夫哈兰

现在我可以在我想要的任何物理地址上使用mmap / dev / mem 但必须要小心:

  

谨慎。出于某种原因,可能会引入CONFIG_X86_PAT。关闭它可能会有一些性能损失,尽管在我的测试中到目前为止如果关闭似乎没有破坏任何东西   杰夫哈兰