简体   繁体   English

如何使用C语言中的“ mmap”命令分配特定的内存区域? (Android NDK)

[英]How do you allocate a specific area of memory using the 'mmap' command in C? (Android NDK)

What is the proper way to allocate a specific region of memory using 'mmap' in C? 在C中使用“ mmap”分配内存的特定区域的正确方法是什么? I've read /proc/self/maps to determine that the area is available. 我已阅读/ proc / self / maps确定该区域可用。

I've tried the following, but it crashes when trying to write to the allocated memory: 我尝试了以下操作,但是在尝试写入分配的内存时会崩溃:

// rdram is defined in header as:  #define rdram ((unsigned int *)0x80000000)
     printf( "rdram=0x%x", (int)rdram );
     printf( "munmapping" );
     munmap ((void*)0x80000000, 0x800000);
     printf( "mmapping" );
     if(mmap ((void*)0x80000000, 0x800000,
            PROT_READ | PROT_WRITE,
            MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
            -1, 0) <= 0)
     {
         printf( "mmap(0x80000000) failed" );
     }
     else
     {
         for (i=0; i<(0x800000/4); i++)
         {
             printf( "writing a zero at 0x%x", (0x80000000 + i) );
             rdram[i]=0;    // <<---------CRASH HERE--------<<
         }
         printf( "done writing zeros" );
      }

It was suggested on my earlier question (which got closed for not being stated clearly), that I am not properly detecting when mmap failed, and that I should use posix_typed_mem_open instead of -1 for the fildes parameter. 有人在我先前的问题(由于未明确说明而关闭)上建议,我没有正确检测到mmap何时失败,因此我应该使用posix_typed_mem_open而不是-1作为fildes参数。 I thought I would try the following (please let me know if there is something wrong with this): 我以为我会尝试以下方法(请告诉我这是否有问题):

 int m;
 int p;

 printf( "rdram=0x%x", (int)rdram );
 printf( "munmapping" );
 munmap ((void*)0x80000000, 0x800000);
 printf( "posix_typed_mem_open" );
 p = posix_typed_mem_open( "/memory/ram", O_RDWR, POSIX_TYPED_MEM_ALLOCATE_CONTIG );
 printf( "mmapping" );
 m = (int) mmap ((void*)0x80000000, 0x800000,
             PROT_READ | PROT_WRITE,
             MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
             p, 0);
 if( m == (int) MAP_FAILED )
 {
     printf( "mmap failed" )
 }
 else
 {
     for (i=0; i<(0x800000/4); i++)
     {
         printf( "writing a zero at 0x%x", (0x80000000 + i) );
         rdram[i]=0;
     }
     printf( "done writing zeros" );
 }

This is being run on one of one of my testers' devices (the memory mapping on my device is not suitable), so I'd like to know this makes sense before I have him run it to see what kind of output he gets. 这是在我的测试仪之一的设备上运行的(我的设备上的内存映射不合适),所以我想知道这一点是否有意义,然后再让他运行它以查看他得到什么样的输出。

Are you trying to map virtual or physical memory? 您是否要映射虚拟物理内存? If virtual, then you're on right track but might be hitting some issue in Android with your first approach. 如果是虚拟的,那么您将走上正确的道路,但您的第一种方法可能会遇到Android中的某些问题。 Typed memory objects are not required, however, the kernel takes the first argument to mmap as hint only . 输入的内存对象不是必需的,但是,内核将mmap的第一个参数仅用提示 The ENOMEM suggests that you're hitting some form of limit set on your device, though. ENOMEM建议您达到设备上某种形式的限制。

If your goal was allocation of physical memory, what you need to do is to mmap /dev/mem (requires root, or changing permissions on it) with the offset set to address you want. 如果您的目标是分配物理内存,则要做的是使用偏移量设置为您想要的地址来映射/ dev / mem(需要root或更改其权限)。

Just try like this 像这样尝试

/* 使用映射 /dev/zero 分配内存页 */
memFd = open("/dev/zero", O_RDONLY);
if (memFd < 0) {
    jniThrowException(mJniEnv, RUNTIME_EXCEPTION, "open /dev/zero fail!");

    return MR_FAILED;
}

memBase = (char *) mmap(NULL, memLen, PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE, memFd, 0);
if (memBase == MAP_FAILED) {
    jniThrowException(mJniEnv, OUTOFMEMORY_ERROR, "");
    close(memFd);

    return MR_FAILED;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM