MMAP(2)

NAME
mmap - map an open file into the process's address space

SYNOPSIS
#include <sys/types.h>
#include <sys/mman.h>
mmap(addr, len, prot, share, fd, pos)
caddr_t	addr;	/* starting virt-addr */
int	len;	/* length (bytes) to map */
int	prot;	/* RO, RW encoding */
int	share;	/* private/shared modifications */
int	fd;	/* open file to be mapped */
off_t	pos;	/* where in file to begin map */

DESCRIPTION
Mmap causes the file referenced by fd, starting at byte pos for len bytes in the file, to be mapped into the calling process's address space, starting at virtual address addr for len bytes, using protection specified by prot; modifications to the mapped memory are either private to the process or shared, as specified by share. Mmap can be used to allocate regions of shared memory, to map files into memory, and to access special regions of the physical address space.

Fd must reference an open regular (IFREG) or character special (IFCHR) file. The device driver that implements the IFCHR special file must support mapping for this to succeed. Typically, a regular file is used to map shared memory.

The share argument specifies whether modifications to a mapped file are to be kept private to the calling process or shared with other processes accessing the file. If share is MAP_SHARED, all modifications to the file are shared with others who have it concurrently mapped. If share is MAP_PRIVATE, all modifications are local to the calling process; this doesn't restrict other processes from mapping the file. MAP_SHARED and MAP_PRIVATE have no relation to flock(2), and do not restrict read and write system-calls. If share is MAP_ZEROFILL, the space indicated from addr for len bytes is replaced by private pages that are zero-filled when referenced. MAP_ZEROFILL ignores the fd argument, and pos is ignored other than being checked for alignment (specifying fd and pos = 0 is recommended).

The prot argument should be PROT_WRITE for write access to the mapped region, PROT_READ for read access, PROT_EXEC for executable access. These values can be ORed to obtain read-write access, etc. For programming convenience, PROT_RDWR is defined as (PROT_READ|PROT_WRITE). The file access permissions on fd must allow the requested access. The prot argument affects only the calling process; other processes mapping the same file may have different access.

The addr, len, and pos arguments must be integral multiples of the system page size, as defined by getpagesize(2). It is possible to map over previously mapped pages. If addr and len specify a nonexistent part of the process's address space, the process's data segment is grown to accommodate the request, and (for non parallel processes) the process ``break'' (see brk(2)) is set to the high end of the mapped region. When mmap is used with parallel processes the value of ``break'' is unchanged and subtleties exists as explained in the "NOTES" section below. Reference to any ``holes'' between the mapped region and the rest of the data segment result in a segmentation fault (SIGSEGV). mmap does allow mapping over text pages. It does not allow mapping over private stack pages.

When memory is mapped to a regular file, the file acts like a paging area for the mapped memory region. Read and write operations to mapped regions of the file also affect the corresponding memory. The memory contents are copied out to the file when the process is swapped or when it exits, or when the region is otherwise unmapped by the last process that has it mapped. For programs that use shared memory but do not need a permanent disk image of the memory, the file associated with fd can be unlinked (see unlink(2)) even before the call to mmap: if the file is unlinked when the region is unmapped, the disk space will not be updated.

Regular files have their size rounded up to a file-system block boundary. Any non-existent space in the file at the time of the mmap request (for example, in a sparse file) is allocated, and filled with zeroes when referenced. Both of these operations require write access to the file.

The type of file referenced may impose further restrictions on the pos, offset, or other parameters. Refer to the manual entry of the relevant device driver (for example, pmap(4)) for details.

Mmap can be called multiple times with the same file descriptor, resulting in several (possibly overlapping) mapped regions. A process can have up to 8 regions mapped simultaneously; mappings that are completely overlapped by subsequent mappings are not counted in this total. Mappings which use the same file descriptor, and addr and pos arguments which align virtually with a previous mapping, also don't count in this total; the simplest case is mapping more of a file, starting from the end of a previous mapping.

All mapped files remain mapped in both the parent and child process after a fork. All flavors of the exec and exit system calls, when successful, remove all maps the calling process had established. A child of a vfork that has not yet execed a new image cannot successfully execute mmap.

There are three types of mapping: paged, physical, and non-paged memory. The type of mapping is determined by the type of file being mapped. Paged maps support shared memories and mapped regular files. Physical maps deal with hardware that has restrictive access capability (for example, the MULTIBUS address space, including Atomic Lock Memory). Non-paged memory maps are typically used for special reserved areas of system memory; they are assumed to behave exactly like memory, supporting accesses of arbitrary size and alignment, DMA, etc.

System services (raw IO, read/write, stat, etc.) are supported in paged and non-paged memory maps; attempts at such services in physically mapped address space result in an error, typically EFAULT. Core dumps include a copy of any mapped address space; however, physically mapped addresses read as zero.

Regular files (IFREG) are always page-mapped. Character special files (IFCHR) can support paged, physical, or non-paged maps, depending on the underlying hardware. Physical and non-paged maps are always valid in the process address space; references won't cause a page fault.

When mmap increases a program's address space, it also attempts to increase its allowable resident set size.

NOTES
1) Interaction of mmap and libpps:

Parallel programs have a different virtual memory layout than regular programs, and this effects the way mmap should be used. The virtual memory layout of the shared processes contains additional regions of shared data, shared stack and shared heap. Any mmapped region should be at an address well beyond the highest expected value of the process's shared heap (see Guide to Parallel Programming). The effective ``break'' value of a parallel process may be obtained by calling the routine shsbrk(0), instead of sbrk(0). The address to mmap should then be chosen well above this value. Once mmap succeeds for parallel program, the ``break'' value for the system will remain unchanged, and it is up to the user's program to keep track of the mmaped addresses.

RETURN VALUE
Mmap returns zero when successful. Otherwise it returns -1 and places the error number in the global variable errno.

EXAMPLES
The following code sets up a 1-Mbyte region of shared memory at the first page boundary above the current program ``break.'' This region will be shared with the process's children and with any other process that maps the file ``shmem''. pgsz = getpagesize(); shm_base = (char *) ( ((int)sbrk(0) + (pgsz-1)) & ~(pgsz-1) ); fd = open ("shmem", O_CREAT | O_RDWR, 0666); mmap (shm_base, 0x100000, PROT_RDWR, MAP_SHARED, fd, 0); Please note that with parallel programs the value of curshbrk is used instead of sbrk(0) as shown below: pgsz = getpagesize(); shm_base = (char *) ( ((int)shsbrk(0) + (pgsz-1)) & ~(pgsz-1) ); fd = open ("shmem", O_CREAT | O_RDWR, 0666); mmap (shm_base, 0x100000, PROT_RDWR, MAP_SHARED, fd, 0);

The following code maps the first page of Atomic Lock Memory into the process's virtual address space at address 0x200000. This region will be shared with the process's children and with any other process that maps the file ``/dev/alm/alm00''. pgsz = getpagesize(); fd = open ("/dev/alm/alm00", O_RDWR, 0); mmap (0x200000, pgsz, PROT_RDWR, MAP_SHARED, fd, 0);

ERRORS

[EINVAL]
    Addr, pos, or len is not a multiple of the system page size.

[EINVAL]
    Prot did not specify at least one of PROT_WRITE or PROT_READ; share did not specify MAP_SHARED, MAP_PRIVATE, or MAP_ZEROFILL; or share specified MAP_ZEROFILL but prot did not contain PROT_RDWR.

[EINVAL]
    Fd does not represent a regular or character special file.

[EINVAL]
    The process is the child of a vfork.

[EINVAL]
    The area defined by the addr and len arguments overlaps stack pages of the process.

[ENODEV]
    The device driver indicated by fd does not support mapping.

[ENOMEM]
    There is no swap space for the page table of a mapped regular file, or you are trying to create too large a process.

[EMFILE]
    The system-defined per-process limit on the number of mmaped files (currently 8) was exceeded.

[ENFILE]
    The system-wide limit on the number of mapped regular files was exceeded. This limit is defined by the variable nmfile in /sys/conf/param.c.

[EACCES]
    Fd does not allow the desired access (read or write), or a write-only file descriptor was used.

[EACCES]
    A privately mapped file may not have the mapping specify that the file should be extended; a private mapping is only used to provide a fixed view of the file at the time the mapping was established.

[EACCES]
    A mapped regular file must be extended to a file-system block boundary, or the file must have space allocated, and the file descriptor is read-only.

[ENOSPC]
    A mapped regular file was sparse and there was insufficient space in the file-system to satisfy the request.

[EFBIG]
    The pos and len arguments would create too large a file.

[others]
    Other error values may be returned by some device drivers when requested to map. See the relevant driver manual entry for details.

SEE ALSO
munmap(2), pmap(4), vm_ctl(2), fork(2), exec(2), getpagesize(2), Guide to Parallel Programming

BUGS
A mapped file may not be truncated.

If a file is extended to a file-system block boundary, its original size is lost.

Current restrictions on what parts of the address space can be re-mapped should be lifted.

NOTES
Due to a hardware restriction, PROT_WRITE implies PROT_READ also.

To minimize overhead, mapped regions should be kept as close as possible to the low end of process memory.

Address space holes under the process ``break'' read as zeroes in core files.