As programmers we generally use malloc()
, free()
and similar functions in order to allocate memory. They are provided by glibc()
library. The actual work is done by mmap()
and munmap()
which is a Linux systemcall.
What Does mmap() Function?
mmap()
function or system call will create a mapping in the virtual meory of the current process.The address space consist of multiple pages and each page can be mapped some resource. We can create this mapping for a resources we want to use.
Library
mmap()
and munmap()
functions are provided by sys/mman.h
library. so in order to use we need to include them like below.
#include <sys/mman.h>
Syntax
As mmap()
provides flexible memory mapping it has a lot of parameters to use.
void *mmap(void *addr, size_t lengthint " prot ", int " flags , int fd, off_t offset)
void *addr
is the address we want to start mappingsize_t lengthint
is the size we want to map in as integerPROT_READ|PROT_WRITE|PROT_EXEC
options about pageMAP_ANON|MAP_PRIVATE
options about page
Memory Mapping Types
We have two option about memory mapping for sharing.
MAP_SHARED
will map given page and this will be also visible by other processes.MAP_PRIVATE
will map given page and this will not visible to other processes.
Example
Here is an example which takes a page from start of 2^20
. The default size of the page is 4096
byte so we will map a page with 4096 byte memory.
#include <stdio.h> #include <string.h> #include <sys/mman.h> #include <unistd.h> int main(void) { size_t pagesize = getpagesize(); printf("System page size: %zu bytes\n", pagesize); char * region = mmap( (void*) (pagesize * (1 << 20)), // Map from the start of the 2^20th page pagesize, // for one page length PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, // to a private block of hardware memory 0, 0 ); if (region == MAP_FAILED) { perror("Could not mmap"); return 1; } strcpy(region, "Hello, poftut.com"); printf("Contents of region: %s\n", region); int unmap_result = munmap(region, 1 << 10); if (unmap_result != 0) { perror("Could not munmap"); return 1; } // getpagesize return 0; }
When we compile with the following command the a.out
executable will be generated.
$ gcc main.c

Does not compile
/usr/include/x86_64-linux-gnu/sys/mman.h:57:14: note: expected ‘__off_t {aka long int}’ but argument is of type ‘void *’
something wrong in your code.
several arguments is empy in exemple MMAP
char * region = mmap(
(void*) (pagesize * (1 << 20)), // Map from the start of the 2^20th page
pagesize, // for one page length
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANON|MAP_PRIVATE, // to a private block of hardware memory
,
);
please correct your example
Why are we unmapping only 1024 bytes instead of the pagesize?