简体   繁体   中英

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? I've read /proc/self/maps to determine that the area is available.

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. 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. Typed memory objects are not required, however, the kernel takes the first argument to mmap as hint only . The ENOMEM suggests that you're hitting some form of limit set on your device, though.

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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