mmap(2) mmap(2)
NAME [Toc] [Back]
mmap - map pages of memory
SYNOPSIS [Toc] [Back]
#include <sys/mman.h>
void *mmap(void *addr, size_t len, int prot, int flags,
int fildes, off_t off);
DESCRIPTION [Toc] [Back]
The mmap() function establishes a mapping between a process' address
space and a file. The format of the call is as follows:
pa = mmap(addr, len, prot, flags, fildes, off);
The mmap() function establishes a mapping between the process' address
space at an address pa for len bytes and the file associated with the
file descriptor fildes at offset off for len bytes. The value of pa is
an unspecified function of the argument addr and values of flags,
further described below. A successful mmap() call returns pa as its
result. The address ranges covered by [pa, pa+len] and [off, off+len]
must be legitimate for the possible (not necessarily current) address
space of the process and the file, respectively.
If the size of the mapped file changes after the call to mmap(), the
effect of references to portions of the mapped region that correspond
to added or removed portions of the file is unspecified.
The mmap() function is supported for regular files. Support for any
other type of file is unspecified except for /dev/zero, which is
supported in HP-UX. See also zero(7).
The prot argument determines whether read, write, execute, or some
combination of accesses are permitted to the pages being mapped. The
protection options are defined in <sys/mman.h>:
PROT_READ Page can be read.
PROT_WRITE Page can be written.
PROT_EXEC Page can be executed.
PROT_NONE Page cannot be accessed.
The prot argument can be PROT_NONE, or any combination of the bit-wise
inclusive OR of the values of PROT_READ, PROT_WRITE, and PROT_EXEC.
If PROT_NONE is not specified, the system may grant other access
permissions to the region in addition to those explicitly requested,
except that write access will not be granted unless PROT_WRITE is
specified.
The following combinations of protection modes are supported:
Hewlett-Packard Company - 1 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
PROT_NONE [Toc] [Back]
PROT_READ
PROT_READ|PROT_EXECUTE
PROT_READ|PROT_WRITE
PROT_READ|PROT_WRITE|PROT_EXECUTE
The flags argument provides other information about the handling of
the mapped pages. The options are defined in <sys/mman.h>:
MAP_SHARED Share changes.
MAP_ADDR32 Share changes between 32-bit and 64-bit
processes. Under Adaptive Address Space,
64-bit MPAS (Mostly Private Address Space)
processes cannot specify this flag. See
the Adaptive Address Space Whitepaper for
details.
MAP_PRIVATE Changes are private.
MAP_FIXED Interpret addr exactly.
MAP_FILE Create a mapped file region.
MAP_ANONYMOUS Create an unnamed memory region.
MAP_VARIABLE Place region at implementation-computed
address.
MAP_NORESERVE Evaluate lazy swap space reservation.
MAP_GLOBAL Allocate physical memory from the global
quadrant / octant.
MAP_IO Create a virtual mapping for a physical
I/O address range.
MAP_MEM_INTERLEAVED Physical memory will be interleaved.
MAP_MEM_LOCAL Allocate physical memory from the current
locality domain.
MAP_MEM_FIRST_TOUCH Allocate physical memory from the locality
domain of the first processor to touch
each address.
The MAP_PRIVATE and MAP_SHARED flags control the visibility of write
references to the memory region. Exactly one of these flags must be
specified. A MAP_IO mapping can not be mapped private and must use
the MAP_SHARED flag. The mapping type is retained across a fork().
Hewlett-Packard Company - 2 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
If MAP_SHARED is set in flags, write references to the memory region
by the calling process may change the file and are visible in all
MAP_SHARED mappings of the same portion of the file by any process of
the same executable type. That is, an application compiled as a 32-
bit process will be able to share the same mappings with other 32-bit
processes, and an application compiled as a 64-bit process will be
able to share the same mappings with other 64-bit processes.
If a 64-bit and a 32-bit application want to share the same mapping,
both MAP_ADDR32 and MAP_SHARED must be set in flags by the 64-bit
application. The 32-bit application does not need to set MAP_ADDR32
in flags. When MAP_SHARED is set in flags, write references to the
memory region by the calling process may change the file. Changes are
visible in all 32-bit processes which specify MAP_SHARED and by all
64-bit processes which specify both MAP_SHARED and MAP_ADDR32 for the
same portion of the file. Mappings created using the MAP_IO flag do
not currently support usage of the MAP_ADDR32 flag. Programs running
on PA-RISC platforms may still share between 64-bit and 32-bit
processes by mapping to the 32-bit processes first. Programs running
on Itanium-based platforms will share the mapped range of I/O address
space, but the virtual address range given to a 32-bit process will
differ from that assigned to a 64-bit process.
On Itanium-based platforms, 64-bit MPAS (Mostly Private Address Space)
and MGAS (Mostly Global Address Space) processes can share between
themselves without incurring the cost of aliasing by specifying the
MAP_GLOBAL flag without specifying the MAP_ADDR32 flag. Such mappings
are not accessible by 32-bit processes. See the Adaptive Address
Space Whitepaper for details.
If MAP_PRIVATE is set in flags, write references to the memory region
by the calling process do not change the file and are not visible to
any process in other mappings of the same portion of the file.
It is unspecified whether write references by processes that have
mapped the memory region using MAP_SHARED are visible to processes
that have mapped the same portion of the file using MAP_PRIVATE.
It is also unspecified whether write references to a memory region
mapped with MAP_SHARED are visible to processes reading the file and
whether writes to a file are visible to processes that have mapped the
modified portion of that file, except for the effect of msync().
The MAP_VARIABLE and MAP_FIXED flags control the placement of the
region as described below. Exactly one of these flags must be
selected, with the exception of MAP_IO mappings. MAP_IO regions must
be placed by the system and do not support MAP_FIXED requests. Usage
of MAP_VARIABLE with MAP_IO is recommended, but not required since
MAP_IO implicitly includes this attribute in the request.
Hewlett-Packard Company - 3 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
If MAP_VARIABLE is set in flags, and the requested address addr is
NULL, or if it is not possible for the system to place the region at
the requested address, the region is placed at an address selected by
the system. If the requested address is not a multiple of the page
size returned by sysconf(_SC_PAGE_SIZE), the system treats the address
as if it were rounded up to the next larger page size multiple.
When MAP_FIXED is set in the flags argument, the implementation is
informed that the value of pa must be addr, exactly. If MAP_FIXED is
set, mmap() may return MAP_FAILED and set errno to [EINVAL]. If a
MAP_FIXED request is successful, the mapping established by mmap()
replaces any previous mappings for the process' pages in the range
[pa, pa+len].
When MAP_FIXED is not set, the implementation uses addr in an
unspecified manner to arrive at pa. The pa so chosen will be an area
of the address space which the implementation deems suitable for a
mapping of len bytes to the file. All implementations interpret an
addr value of 0 as granting the implementation complete freedom in
selecting pa, subject to constraints described below. A non-zero value
of addr is taken to be a suggestion of a process address near which
the mapping should be placed. When the implementation selects a value
for pa, it never places a mapping at address 0, replaces any extant
mapping, or maps into dynamic memory allocation areas.
The off argument is constrained to be aligned and sized according to
the value returned by sysconf() when passed _SC_PAGESIZE or
_SC_PAGE_SIZE. When MAP_FIXED is specified, the argument addr must
also meet these constraints. The implementation performs mapping
operations over whole pages. Thus, while the argument len need not
meet a size or alignment constraint, the implementation will include,
in any unmapping operation, any partial page specified by the range
[pa, pa+len].
The MAP_FILE and MAP_ANONYMOUS flags control whether the region to be
mapped is a mapped file region or an anonymous shared memory region.
Exactly one of these flags must be selected.
If MAP_FILE is set in flags, a new mapped file region is created,
mapping the file associated with fildes. off specifies the file byte
offset at which the mapping starts. This offset must be a multiple of
the page size returned by sysconf(_SC_PAGE_SIZE). If the end of the
mapped file region is beyond the end of the file, any reference to an
address in the mapped file region corresponding to an offset beyond
the end of the file results in the delivery of a SIGBUS signal to the
process, unless the address lies in the last partial page
corresponding to the range beyond the end of the file. The last
partial page mapping the range beyond the end of the file is always
initialized to zeros, and any modified portions of the last page of a
file which are beyond the file's end are not written back to the file.
Hewlett-Packard Company - 4 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
If MAP_ANONYMOUS is set in flags, a new memory region is created and
initialized to all zeros. This memory region can be shared only with
descendants of the current process. If the fildes argument is not -1,
an [EINVAL] error is generated. This is not enforced in the current
release, but will be enforced in the next release. The value of off
is meaningless because there is no underlying file object for the
memory region.
If MAP_NORESERVE is set in flags, no swap space is initially reserved
for the private mapping. Without this flag, the creation of a
MAP_PRIVATE region reserves swap space equal to the size of the
mapping. When a page in the mapping is first modified (written to), a
private page is created and the swap space reserved is used to hold
the private copy of the data in the event of a page-out. An initial
write into a page of a MAP_NORESERVE mapping produces results which
depend on the current availability of system swap space, since the
swap space reservation occurs at the time of the first write and only
for the affected page. If the swap space reservation can be made for
the page, the write succeeds as described above. If not, the write
fails and a SIGBUS signal is posted to the writing process for the
effective virtual address. madvise(...,MADV_DONTNEED) on a
MAP_NORESERVE object will release swap space reservations for relevant
pages.
Specifying MAP_GLOBAL in a call to mmap() forces the allocation to
happen from the global quadrant as compared to the private quadrants.
See setmemwindow(1M) for further details.
If MAP_IO is set in flags:
+ The region will represent ranges of I/O memory instead of core
memory. This allows direct access to memory on I/O devices.
I/O space is always mapped with both read and write access
rights, regardless of the actual permissions specified by the
prot argument. Multiple processes can concurrently mmap() a
single I/O memory range. It is the responsibility of the
processes to synchronize their accesses. Successive calls to
mmap() to map the same I/O range must be identical to the
first mapping. Identical mappings have the same address and
size.
+ The process can additionally share I/O space (mapped via
iomap) with a kernel driver. However, this is only possible
if the driver maps in the I/O space with user read/write
access rights using the appropriate driver I/O mapping
services. Any I/O space mapped by drivers with kernel
read/write access rights can not be concurrently mapped by
processes using mmap().
+ Calls using MAP_IO implicitly also use MAP_SHARED and
MAP_VARIABLE as mentioned above. Explicit use of these flags
Hewlett-Packard Company - 5 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
is encouraged for forward compatibility, but not required.
The required arguments to mmap() with MAP_IO set are: addr is
set to NULL, fildes is set to -1, and off is set to the
starting physical address of the I/O range to be mapped. This
address will be either 40, 44 or 64-bits and use of MAP_IO for
32-bit processes is therefore restricted to users of mmap64().
+ The MAP_IO functionality is currently restricted to Real Time
processes or superusers.
Note that the flags MAP_MEM_INTERLEAVED, MAP_MEM_LOCAL, and
MAP_MEM_FIRST_TOUCH involve the placement of physical memory. This is
important only on Cache Coherent Non-Uniform Memory Architecture
(ccNUMA) systems. They will have no effect otherwise. For more
information, see the mpctl(2) manual page. These flags are hints to
the system. If memory of the desired type is not available, the next
most suitable memory is returned instead.
mmap() cannot create a mapped file region unless the file descriptor
used to map the file is open for reading. For a mapped file region
that is mapped with MAP_SHARED, mmap() grants write access permission
only if the file descriptor is open for writing. If a region was
mapped with either MAP_PRIVATE or MAP_ANONYMOUS, mmap() grants all
requested access permissions.
After the successful completion of mmap(), fildes can be closed
without effect on the mapped region or on the contents of the mapped
file. Each mapped region creates a file reference, similar to an open
file descriptor, that prevents the file data from being deallocated.
If an enforcement-mode file lock is in effect for any range of a file,
a call to mmap() to map any range of the file with access rights that
would violate the lock fails. The msem_lock() and msem_unlock()
semaphore interfaces can be used to coordinate shared access to a
region created with the MAP_SHARED flag. The advisory locks of the
lockf() or fcntl() interfaces have no effect on memory mapped access,
but they can be used to coordinate shared access to a MAP_SHARED
mapped file region.
After a call to fork(), the child process inherits all mapped regions
with the same data and the same sharing and protection attributes as
in the parent process. Each mapped file and anonymous memory region
created with mmap() is unmapped upon process exit, and by a successful
call to any of the exec functions.
MAP_NORESERVE attribute is inherited across a fork() call; at the time
of the fork(), swap space for a mapping is reserved in the child only
for dirtied private pages that currently exist in the parent.
Thereafter, the child's mapping reservation policy is as described
above.
Hewlett-Packard Company - 6 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
A SIGBUS signal is delivered to a process when a write reference to a
mapped file region would cause a file system error condition, such as,
exceeding quota or file system space limits.
A SIGBUS signal is delivered to a process upon a write reference to a
region without PROT_WRITE protection, or any reference to a region
with PROT_NONE protection.
A call to mmap() with PROT_EXECUTE specified, but without PROT_WRITE
specified for a MAP_SHARED|MAP_FILE mapping is treated by the system
as the execution of the underlying file. This implies that such a
call fails if the file is currently open for writing or mapped with
MAP_SHARED|PROT_WRITE options by any process, and if the call
succeeds, the file cannot be opened for writing or subsequently mapped
with MAP_SHARED|PROT_WRITE options as long as such mappings are
present. A file's status as an active executable file is determined
only at the time of an exec(), exit(), or mmap() operation.
mprotect() operations on a MAP_FILE|MAP_SHARED mapping have no effect
on the underlying file's status as an active executable file.
The implementation always zero-fills any partial page at the end of a
memory region. Further, the implementation never writes out any
modified portions of the last page of a file that are beyond the end
of the mapped portion of the file. If the mapping established by
mmap() extends into pages beyond the page containing the last byte of
the file, an application reference to any of the pages in the mapping
that are beyond the last page results in the delivery of a SIGBUS or
SIGSEGV signal. The mmap() function adds an extra reference to the
file associated with the file descriptor fildes which is not removed
by a subsequent close() on that file descriptor. This reference is
removed when there are no more mappings to the file. The st_atime
field of the mapped file may be marked for update at any time between
the mmap() call and the corresponding munmap() call. The initial read
or write reference to a mapped region will cause the file's st_atime
field to be marked for update if it has not already been marked for
update.
The st_ctime, st_mtime, and st_atime fields of a file that is mapped
with MAP_SHARED and PROT_WRITE, will be marked for update at some
point in the interval between a write reference to the mapped region
and the next call to msync() with MS_ASYNC or MS_SYNC for that portion
of the file by any process. If there is no such call, these fields
may be marked for update at any time after a write reference if the
underlying file is modified as a result.
There may be implementation-dependent limits on the number of memory
regions that can be mapped (per process or per system). If such a
limit is imposed, whether the number of memory regions that can be
mapped by a process is decreased by the use of shmat() is
implementation-dependent.
Hewlett-Packard Company - 7 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
RETURN VALUE [Toc] [Back]
Upon successful completion, mmap() returns the address, (pa), at which
the mapping was placed. Otherwise, it returns MAP_FAILED (defined in
<sys/mman.h>) and sets errno to indicate the error.
ERRORS [Toc] [Back]
The mmap() function will fail if:
[EBADF] The fildes argument is not a valid open file
descriptor.
[EACCES] The fildes argument is not open for read,
regardless of the protection specified, or fildes
is not open for write and PROT_WRITE was specified
for a MAP_SHARED type mapping, or PROT_EXECUTE was
set for a MAP_SHARED mapping operation and the
underlying file does not have execute permission.
[ENXIO] Addresses in the range [off, off+len] are invalid
for fildes.
[EINVAL] The addr argument (if MAP_FIXED was specified) or
off is not a multiple of the page size as returned
by sysconf(), or are considered invalid by the
implementation.
[EINVAL] The value of flags is invalid (neither MAP_PRIVATE
nor MAP_SHARED is set).
[EINVAL] The mapping already exists in 64-bit address
space, but the application performing the current
mmap() request has been compiled as a 32-bit
executable.
[EINVAL] The mapping already exists in 32-bit address
space, but the application performing the current
mmap() request has been compiled as a 64-bit
executable and did not specify MAP_ADDR32 in the
flags argument.
[EINVAL] The value of off+len exceeds the maximum supported
offset for mapped files.
[EINVAL] The mapping request used the MAP_IO flag and the
requested range is not a valid range of I/O
memory, the requested range is already mapped as
restricted to kernel usage, or the mapping is for
an address range which overlaps but is not equal
to an existing mapping.
Hewlett-Packard Company - 8 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
[EMFILE] The number of mapped regions would exceed an
implementation-dependent limit (per process or per
system).
[ENODEV] The fildes argument refers to a file whose type is
not supported by mmap().
[ENOMEM] MAP_FIXED was specified, and the range [addr,
addr+len] exceeds that allowed for the address
space of a process. Or, MAP_FIXED was not
specified and there is insufficient room in the
address space to effect the mapping.
[EOVERFLOW] The file is a regular file and the value of
off+len exceeds the offset maximum established in
the open file description associated with fildes.
[EPERM] The mapping request used the MAP_IO flag and the
calling process does not have superuser privilege
and is not a Real Time process.
[ETXTBSY] MAP_SHARED and MAP_FILE are set, and PROT_EXECUTE
is set and PROT_WRITE is not set, and the file
being mapped is currently open for writing.
DEPENDENCIES [Toc] [Back]
PA-RISC Architecture
Because the PA-RISC memory architecture utilizes a globally shared
virtual address space between processes and discourages multiple
virtual address translations to the same physical address, all
concurrently existing MAP_SHARED mappings of a file range must share
the same virtual address offsets and hardware translations. PA-RISCbased
HP-UX systems allocate virtual address ranges for shared memory
and shared mapped files in the range 0x80000000 through 0xefffffff for
those applications compiled as 32-bit executables or for those 64-bit
applications which specify MAP_SHARED and MAP_ADDR32 in the flags
argument of the mmap() function. For applications compiled as 64-bit
executables which specify MAP_SHARED and do not specify MAP_ADDR32,
the shared mapped files are in the range 0x00000011 00000000 through
0x000003ff ffffffff and 0xc0000000 00000000 through 0xc00003ff
ffffffff. These address ranges are used globally for all memory
objects shared between processes.
This implies the following:
+ Any single range of a file cannot be mapped multiple times
into different virtual address ranges.
+ After the initial MAP_SHARED mmap() of a file range, all
subsequent MAP_SHARED calls to mmap() to map the same range of
a file must either specify MAP_VARIABLE in flags and inherit
Hewlett-Packard Company - 9 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
the virtual address range the system has chosen for this
range, or specify MAP_FIXED with an addr that corresponds
exactly to the address chosen by the system for the initial
mapping. Only after all mappings for a file range have been
destroyed can that range be mapped to a different virtual
address.
+ In most cases, two separate calls to mmap() cannot map
overlapping ranges in a file. The virtual address range
reserved for a file range is determined at the time of the
initial mapping of the file range into a process address
space. The system allocates only the virtual address range
necessary to represent the initial mapping. As long as the
initial mapping exists, subsequent attempts to map a different
file range that includes any portion of the initial range may
fail with an ENOMEM error if an extended contiguous address
range that preserves the mappings of the initial range cannot
be allocated.
+ Separate calls to mmap() to map contiguous ranges of a file do
not necessarily return contiguous virtual address ranges. The
system may allocate virtual addresses for each call to mmap()
on a first available basis.
+ The use of MAP_FIXED is strongly discouraged because it is not
portable. Using MAP_FIXED is generally unsuccessful on this
implementation, and when it is successful, it may prevent the
system from optimally allocating virtual address space.
MAP_FIXED is discouraged, but there are some applications which by
design must fix pointer offsets into file data. The application must
map the file at a specific address in order for the file offsets
embedded in the file to make sense.
Processes cannot control the usage of global virtual address space,
but they can control what happens within their private data area. The
PA-RISC version of HP-UX allows a single process to exclusively map a
file MAP_SHARED into its private data space. When a process specifies
MAP_SHARED and MAP_FIXED with a private data address (i.e. second
quadrant for 32-bit executable, third quadrant for 64-bit executable),
the kernel interprets this as an exclusive mapping of the file. The
request will only succeed if no other processes in the system
currently have that file mapped through MAP_SHARED. If the file is
already mapped the caller receives an EBUSY error. If the call is
successful, the calling process is the only process allowed to map
that file using MAP_SHARED until it unmaps the file using munmap().
Because it is exclusive, the mmap() is not inherited across fork().
When a file is exclusively mapped only MAP_PRIVATE mappings are
allowed by other processes.
Hewlett-Packard Company - 10 - HP-UX 11i Version 2: August 2003
mmap(2) mmap(2)
If a MAP_PRIVATE mapping is created of a file for which a MAP_SHARED
mapping exists, a separate copy of a page for the MAP_PRIVATE mapping
is created at the time of the first access to the page through the
private mapping.
APPLICATION USAGE [Toc] [Back]
Use of mmap() may reduce the amount of memory available to other
memory allocation functions.
Use of MAP_FIXED may result in unspecified behavior later in the use
of brk(), sbrk(), malloc(), and shmat(). The use of MAP_FIXED is
discouraged, as it may prevent an implementation from making the most
effective use of resources.
The application must ensure correct synchronization when using mmap()
in conjunction with any other file access method, such as read() and
write(), standard input/output, and shmat().
The mmap() function allows access to resources via address space
manipulations, instead of read()/write(). Once a file is mapped, all
a process has to do to access it is use the data at the address to
which the file was mapped. Using pseudo-code to illustrate the way an
existing program might be changed to use mmap(), the following:
fildes = open(...)
lseek(fildes, some_offset)
read(fildes, buf, len)
/* use data in buf */
becomes:
fildes = open(...)
address = mmap(0, len, PROT_READ, MAP_PRIVATE, fildes, some_offset)
/* use data at address */
AUTHOR [Toc] [Back]
mmap() was developed by HP, AT&T, and OSF.
SEE ALSO [Toc] [Back]
creat64(2), exec(2), fcntl(2), fork(2), lockf(2), madvise(2),
mpctl(2), mprotect(2), msem_init(2), msem_lock(2), msem_unlock(2),
msync(2), munmap(2), pset_ctl(2), shmop(2), sysconf(2), truncate(2),
mman(5), stat(5), zero(7), Adaptive Address Space Whitepaper.
STANDARDS CONFORMANCE [Toc] [Back]
mmap(): AES, SVID3
Hewlett-Packard Company - 11 - HP-UX 11i Version 2: August 2003 [ Back ] |