mmap CMA区域在/dev/mem上

时间:2023-01-18 17:51:27

I need reserve 256-512 Mb of continuous physical memory and have access to this memory from the user space.
I decided to use CMA for memory reserving.
Here are the steps on my idea that must be performed:

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

  1. Reservation required amount of memory by CMA during system booting.
  2. 在系统引导过程中,CMA请求的内存数量。
  3. Parsing of CMA patch output which looks like for example: "CMA: reserved 256 MiB at 27400000" and saving two parameters: size of CMA area = 256*1024*1024 bytes and phys address of CMA area = 0x27400000.
  4. CMA patch输出的解析如下:“CMA:在27400000保留256 MiB”,保存两个参数:CMA area的大小= 256*1024*1024字节,以及CMA area的phys地址= 0x27400000。
  5. Mapping of CMA area at /dev/mem file with offset = 0x27400000 using mmap(). (Of course, CONFIG_STRICT_DEVMEM is disabled) It would let me to read data directly from phys memory from user space.
  6. 使用mmap()对/dev/mem文件中的CMA区域进行映射,用偏移量= 0x27400000。(当然,CONFIG_STRICT_DEVMEM被禁用)它允许我直接从用户空间的phys内存读取数据。

But the next code make segmentation fault(there size = 1Mb):

但下一段代码出现分割错误(其中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];
}

Output of this code: "mmap: Invalid argument".

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

When I changed offset = 0x27400000 on 0, this code worked fine and program displayed trash. It also work for alot of offsets which I looked at /proc/iomem. According to information from /proc/iomem, phys addr of CMA area (0x27400000 on my system) always situated in System RAM.

当我在0上更改偏移量= 0x27400000时,这段代码运行良好,程序显示垃圾。它也适用于很多偏移量,我看了/proc/ iomemem。根据/proc/iomem的信息,CMA区域的phys addr(系统上的0x27400000)始终位于系统RAM中。

Does anyone have any ideas, how to mmap CMA area on /dev/mem? What am I doing wrong? Thanks alot for any help!

大家有什么想法吗,如何在/dev/mem上映射CMA区域?我做错了什么?非常感谢你的帮助!

1 个解决方案

#1


2  

Solution to this problem was suggested to me by Jeff Haran in kernelnewbies mailing list.
It was necessary to disable CONFIG_x86_PAT in .config and mmap() has started to work!

Jeff Haran在kernelnewbies邮件列表中建议我解决这个问题。在.config和mmap()中禁用CONFIG_x86_PAT是必要的!

If CONFIG_X86_PAT is configured you will have problems mapping memory to user space. It basically implements the same restrictions as CONFIG_STRICT_DEVMEM.
Jeff Haran

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

Now I can mmap /dev/mem on any physical address I want.
But necessary to be careful:

现在我可以在任何物理地址上映射/dev/mem。但必须小心:

Word of caution. CONFIG_X86_PAT was likely introduced for a reason. There may be some performance penalties for turning this off, though in my testing so far turning if off doesn’t seem to break anything.
Jeff Haran

谨慎的道。引入CONFIG_X86_PAT是有原因的。关闭它可能会对性能造成一些影响,尽管在我目前的测试中,如果关闭它,似乎不会破坏任何东西。杰夫哈兰

#1


2  

Solution to this problem was suggested to me by Jeff Haran in kernelnewbies mailing list.
It was necessary to disable CONFIG_x86_PAT in .config and mmap() has started to work!

Jeff Haran在kernelnewbies邮件列表中建议我解决这个问题。在.config和mmap()中禁用CONFIG_x86_PAT是必要的!

If CONFIG_X86_PAT is configured you will have problems mapping memory to user space. It basically implements the same restrictions as CONFIG_STRICT_DEVMEM.
Jeff Haran

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

Now I can mmap /dev/mem on any physical address I want.
But necessary to be careful:

现在我可以在任何物理地址上映射/dev/mem。但必须小心:

Word of caution. CONFIG_X86_PAT was likely introduced for a reason. There may be some performance penalties for turning this off, though in my testing so far turning if off doesn’t seem to break anything.
Jeff Haran

谨慎的道。引入CONFIG_X86_PAT是有原因的。关闭它可能会对性能造成一些影响,尽管在我目前的测试中,如果关闭它,似乎不会破坏任何东西。杰夫哈兰