/ dev / mem上的mmap CMA区域

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

  1. CMA在系统启动时预留所需的内存量。
  2. parsingCMA补丁输出,例如:“CMA:27400000保留256MB”,保存CMA区的大小= 256 * 1024 * 1024字节,CMA区的物理地址= 0x27400000这两个参数。
  3. 使用mmap()将位于/ dev / mem文件的CMA区域映射为offset = 0x27400000。 (当然,CONFIG_STRICT_DEVMEM被禁用)它可以让我直接从用户空间的内存中读取数据。

但是下一个代码会导致分段错误(size = 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:无效参数”。

当我改变偏移= 0x27400000 0,这个代码工作正常,程序显示垃圾。 它也适用于我看/ proc / iomem的偏移量。 根据/ proc / iomem的信息,CMA区域(我的系统上的0x27400000)的phys addr总是位于系统RAM中。

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

Jeff Hawran在kernelnewbies邮件列表中向我推荐了这个问题的解决方案。
有必要在.config中禁用CONFIG_x86_PAT,并且mmap()已经开始工作了!

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

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

谨慎的话。 CONFIG_X86_PAT可能是由于某种原因而引入的。 可能会有一些性能处罚,关闭,虽然在我的测试到目前为止,如果关闭似乎不会破坏任何东西。
杰夫·哈兰