![]() |
![]() |
![]() |
Map a memory region into a process's address space
#include <sys/mman.h> void * mmap( void * addr, size_t len, int prot, int flags, int fildes, off_t off ); void * mmap64( void * addr, size_t len, int prot, int flags, int fildes, off64_t off );
libc
A region within the object beginning at off and continuing for len bytes is mapped into the caller's address space at the location returned by the mmap() function.
The arguments are as follows:
Protection | Description |
---|---|
PROT_EXEC | The region can be executed. |
PROT_NOCACHE | Disable caching of the region (e.g. can be used to access dual-ported memory). |
PROT_NONE | The region can't be accessed. |
PROT_READ | The region can be read. |
PROT_WRITE | The region can be written. |
Map type | Description |
---|---|
MAP_ANON | Similar to MAP_PRIVATE but the fildes parameter must be NOFD. The allocated memory is zero-filled. This is equivalent to opening /dev/zero and mapping it with MAP_PRIVATE. |
MAP_PRIVATE | The mapping is private to the calling process. It allocates system RAM and copies the current object. |
MAP_SHARED | The mapping may be shared by many processes. |
The following flags may be ORed in to the above type to further define the mapping:
Map type | Description |
---|---|
MAP_BELOW16M | Used with MAP_PHYS | MAP_ANON. The allocated memory area resides in physical memory below 16M. This is important for using DMA with ISA bus devices. |
MAP_FIXED | Map object to the address specified by addr.
If this area is already mapped, the call changes the existing mapping of the area.
MAP_FIXED should be used with caution.
Not all memory models will support it.
In general, you should only assume that you can MAP_FIXED
at an address (and size) which was returned by calling
mmap() without MAP_FIXED in your code.
A memory area being mmap()'d with MAP_FIXED will first be munmap()'d by the system using the same memory area. See munmap() for details. |
MAP_LAZY | Acquiring system memory and copying, or zero filling, the MAP_PRIVATE or MAP_ANON pages can be delayed until an access to the area has occurred. If this is set and there's no system memory at the time of the access, the thread will get a SIGBUS with a code of BUS_ADRERR. A hint to the memory manager. |
MAP_PHYS | Specifies that physical memory is required.
The fildes parameter must be NOFD.
When used with MAP_PRIVATE or MAP_SHARED,
the offset specifies the exact physical address to map (e.g. for video frame buffers),
and is equivalent to opening /dev/mem.
If used with MAP_ANON, then physically contiguous memory is allocated.
MAP_NOX64K and MAP_BELOW16M are used to further define the MAP_ANON allocated memory (useful on x86 only). You should use mmap_device_memory() instead of MAP_PHYS. |
MAP_NOX64K | (Useful on x86 only). Used with MAP_PHYS | MAP_ANON. The allocated memory area won't cross a 64K boundary. This may be important to some DMA devices. If more than 64K is requested, the area begins on a 64K boundary. |
MAP_STACK | (Useful on x86 only). This flag tells the memory allocator what the MAP_ANON memory will be used for. It's only a hint. |
Using the mapping flags described above, a process can easily share memory between processes:
/* Map in a shared memory region */ fd = shm_open( "/datapoints", O_RDWR, 0777 ); addr = mmap( 0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
Or share memory with hardware such as video memory on an x86 platform:
/* Map in VGA display memory */ addr = mmap( 0, 65536, PROT_READ|PROT_WRITE, MAP_PHYS|MAP_SHARED, NOFD, 0xa0000 );
Or allocate a DMA buffer for a bus-mastering PCI network card:
/* Allocate a physically contiguous buffer */ addr = mmap( 0, 262144, PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_PHYS|MAP_ANON, NOFD, 0 );
The address of the mapped-in object, or MAP_FAILED if an error occurred (errno is set).
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include <sys/mman.h> main() { int i; unsigned char *addr, c; /* Map BIOS ROM */ addr = mmap(0, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_PHYS, NOFD, 0xf0000); if (addr == MAP_FAILED) { fprintf(stderr, "mmap failed : %s\n", strerror(errno)); return EXIT_FAILURE; } printf("Map addr is %6.6X\n", addr); for (i = 0; i < 3 * 80; ++i) { c = *addr++; if (c >= ' ' && c <= 0x7f) putchar(c); else putchar('.'); } return EXIT_SUCCESS; }
mmap() is POSIX 1003.1; mmap64() is for large-file support
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | Yes |
Thread | Yes |
mmap_device_memory(), munmap()
![]() |
![]() |
![]() |