|PMAP(9)||Kernel Developer's Manual||PMAP(9)|
pmapmodule describes how the physical mapping is done between the user-processes and kernel virtual addresses and the physical addresses of the main memory, providing machine-dependent translation and access tables that are used directly or indirectly by the memory-management hardware. The
pmaplayer can be viewed as a big array of mapping entries that are indexed by virtual address to produce a physical address and flags. These flags describe the page's protection, whether the page has been referenced or modified and other characteristics.
pmap interface is consistent across
all platforms and hides the way page mappings are stored.
pmap_init() function is called from
the machine-independent uvm(9)
initialization code, when the MMU is enabled.
pmapmodules to avoid blocking interrupts when manipulating data structures or holding locks. Unmanaged mappings may only be entered into the kernel's virtual address space. The modified/referenced bits must be tracked on a per-page basis, as they are not attributes of a mapping, but attributes of a page. Therefore, even after all mappings for a given page have been removed, the modified/referenced bits for that page must be preserved. The only time the modified/referenced bits may be cleared is when uvm(9) explicitly calls the
pmap_clear_reference() functions. These functions must also change any internal state necessary to detect the page being modified or referenced again after the modified/referenced state is cleared.
Mappings entered by
managed, mappings entered by
pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags);
va, paddr_t pa,
pmap, vaddr_t sva,
pmap_enter() function creates a
managed mapping for physical page pa at the specified
virtual address va in the target physical map
pmap with protection specified by
The flags argument contains protection bits (the same bits used in the prot argument) indicating the type of access that caused the mapping to be created. This information may be used to seed modified/referenced information for the page being mapped, possibly avoiding redundant faults on platforms that track modified/referenced information in software. Other information provided by flags:
pmap_enter() is allowed to fail. If this flag is not set, and the
pmap_enter() call is unable to create the mapping, perhaps due to insufficient resources, the
pmapmodule must panic.
The access type provided in the flags argument will never exceed the protection specified by prot.
pmap_enter() function is called by the
fault routine to establish a mapping for the page being faulted in. If
pmap_enter() is called to enter a mapping at a
virtual address for which a mapping already exists, the previous mapping
must be invalidated.
pmap_enter() is sometimes
called to change the protection for a pre-existing mapping, or to change the
“wired” attribute for a pre-existing mapping.
pmap_kenter_pa() function creates an
unmanaged mapping of physical address pa at the
specified virtual address va with the protection
specified by prot.
pmap_remove() function removes the
range of virtual addresses sva to
eva from pmap, assuming proper
pmap_remove() is called during an unmap
operation to remove low-level machine dependent mappings.
pmap_kremove() function removes an
unmanaged mapping at virtual address va of size
A call to
pmap_update() must be made after
pmap_kremove() to notify the
pmap layer that the mappings need to be made
pmap_unwire(pmap_t pmap, vaddr_t va);
pmap, vaddr_t sva,
vm_page *pg, vm_prot_t prot);
pmap_unwire() function clears the
wired attribute for a map/virtual-address pair. The mapping must already
exist in pmap.
pmap_protect() function sets the
physical protection on range sva to
eva, in pmap.
pmap_protect() function is called
during a copy-on-write operation to write protect copy-on-write memory, and
when paging out a page to remove all mappings of a page. The
pmap_page_protect() function sets the permission for
all mapping to page pg. The
pmap_page_protect() function is called before a
pageout operation to ensure that all pmap references to a page are
pmap_is_modified(struct vm_page *pg);
pmap_clear_modify() functions read/set the modify
bits on the specified physical page pg. The
pmap_clear_reference() functions read/set the
reference bits on the specified physical page pg.
pmap_is_modified() functions are called by the
pagedaemon when looking for pages to free. The
pmap_clear_modify() functions are called by the
pagedaemon to help identification of pages that are no longer in demand.
pmap_copy_page(struct vm_page *src, struct vm_page *dst);
pmap_copy_page() function copies the
content of the physical page src to physical page
pmap_zero_page() function fills
page with zeroes.
pmap_create() function creates an
instance of the pmap structure.
pmap_reference() function increments
the reference count on pmap.
pmap_destroy() function decrements the
reference count on physical map pmap and retires it
from service if the count drops to zero, assuming it contains no valid
pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp);
Wired memory allocation before the virtual memory system is
bootstrapped is accomplished by the
pmap_steal_memory() function. After that point, the
kernel memory allocation routines should be used.
pmap_growkernel() function can
preallocate kernel page tables to a specified virtual address.
pmap_update() function notifies the
pmap module to force processing of all delayed
actions for all pmaps.
pmap_collect() function informs the
pmap module that the given pmap is
not expected to be used for some time, giving the
pmap module a chance to prioritize. The initial
bounds of the kernel virtual address space are returned by
pmap_copy() function copies the range
specified by src_addr and
src_len from src_pmap to the
range described by dst_addr and
dst_len in dst_map.
pmap_copy() is called during a
fork(2) operation to give the
child process an initial set of low-level mappings.
pmapmodule is based on Mach 3.0. The introduction of uvm(9) left the
pmapinterface unchanged for the most part.
pmap_update() should be mandatory.
|December 31, 2008||OpenBSD-5.1|