Get the physical address of a virtually mapped memory block
Synopsis:
#include <sys/mman.h>
int mem_offset( const void * addr,
int fd,
size_t length,
off_t * offset,
size_t * contig_len );
int mem_offset64( const void * addr,
int fd,
size_t length,
off64_t * offset,
size_t * contig_len );
Arguments:
- addr
- The address of the memory block whose offset and contiguous length you want to get.
- fd
- This must be NOFD, or the function will fail.
- length
- The length of the block of memory that you want the offset for.
- offset
- A pointer to a location where the function can store the offset of the memory block.
- contig_len
- NULL, or a pointer to a location where the function can store either
length or the length of the largest contiguous block of memory
that's currently mapped to the calling process starting at addr,
whichever is smaller.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually
included automatically.
Description:
The mem_offset() and mem_offset64() functions set the
variable pointed to by offset to the offset into
/dev/mem of addr (i.e., its physical address). The
mem_offset64() function is a large-file support version of
mem_offset().
Note:
- In QNX Neutrino 6.6 or later, the large-file support functions and data types appear
in the name space only if you define _LARGEFILE64_SOURCE when you compile
your code. For more information, see Classification in What's in
a Function Description?
- If the physical address isn't a valid off_t value,
mem_offset() will fail with errno set to
EOVERFLOW. This is typically the case with many ARM systems, and you
should use mem_offset64() to get the physical address.
- These functions also cause the initial copying or zero-filling of
MAP_PRIVATE or MAP_ANON pages.
- For best performance results, you should cache the result of
mem_offset(), rather than repeatedly call the function for a given
virtual address.
In QNX Neutrino 7.0 or later, these functions succeed only if the memory in question is
locked (either explicitly with an mlock() or mlockall() call, or implicitly, such as when an entire
process or system is fully locked).
To get the offset and length of a mapped typed memory block, use posix_mem_offset() or
posix_mem_offset64().
Note the difference between mem_offset() and
posix_mem_offset():
- Treat mem_offset() as the QNX function for translating virtual
addresses into physical addresses. Thus, this function should not be confused with
similar-sounding functions.
- On the other hand, posix_mem_offset() is meant to return the
logical offset from the beginning of the typed memory object.
Returns:
- 0
- Success.
- -1
- An error occurred (errno is
set).
Errors:
- EACCES
- The process hasn't mapped memory at the given address addr, or the
address is of MAP_LAZY pages that aren't yet memory-resident.
- EAGAIN
- (QNX Neutrino 7.0 or later) The memory isn't locked. The returned offset might
correspond to the physical address associated with the given virtual one, but don't rely
on it for any functionality. The location that contig_len points to
might also be updated. These values are transient and are reported back as a
debugging/testing aid only.
- ENODEV
- The file descriptor fd isn't NOFD.
- EOVERFLOW
- This error is specific to mem_offset() and is returned when the
address is too large for the 32-bit off_t; use
mem_offset64() instead.
Examples:
off64_t offset;
if(mem_offset64(addr, NOFD, 1, &offset, NULL) == -1)
{
/* Error */
}
else
{
/* offset contains the physical address of the memory
mapped at addr. */
}
Classification:
QNX Neutrino
Safety: |
|
Cancellation point |
No |
Interrupt handler |
No |
Signal handler |
Yes |
Thread |
Yes |