shared
, copy
,or none
. If a page ismarked shared
in a givenmap, child tasks share this page for reading and writing. If a pageis marked copy
, childtasks get a copy of this page (using copy-on-write). If a page ismarked none
, the child’spage is left unallocated.pmap
systemactually handles page tables, translation lookaside buffers, segments,and so on, depending on the design of the underlying hardware.fork
),a shadow object is created. A shadow object is initiallyempty, and contains a reference to another object. When the contentsof a page are modified, the page is copied from the parent objectinto the shadow object and then modified. When reading data from apage, if that page exists in the shadow object, the page listedin the shadow object is used. If the shadow object has no copy ofthat page, the original object is consulted. A series of shadowobjects pointing to shadow objects or original objects is knownas a shadow chain.fork
isfrequently followed by exec
,which replaces all of the material being shadowed, long chains arerare. Further, Mach automatically garbage collects shadow objects,removing any intermediate shadow objects whose pages are no longerreferenced by any (nondefunct) shadow object. It is even possiblefor the original object to be released if it no longer containspages that are relevant to the chain.vm_map
and vm_allocate
,which can be used to map file data or anonymous memory into theaddress space. This is possible only because the address space isinitially sparse. In general, an application can either map a file intoits address space (through file mapping primitives, abstracted byBSD) or it can map an object (after being passed a handle to thatobject). In addition, a task can change the protections of the objectsin its address space and can share those objects with other tasks.vm_map_entry
structurecontains task-specific information about an individual mapping alongwith a reference to the backing object. In essence, it is the gluebetween an VM object and a VM map.is_submap
isa Boolean value that tells whether this map entry is a normal VM objector a submap.A submap is a collection of mappings that is part of a larger map. Submapsare often used to group mappings together for the purpose of sharingthem among multiple Mach tasks, but they may be used for many purposes.What makes a submap particularly powerful is that when several taskshave mapped a submap into their address space, they can see eachother’s changes, not only to the contents of the objects in themap, but to the objects themselves. This means that as additionalobjects are added to or deleted from the submap, they appear inor disappear from the address spaces of all tasks that share thatsubmap.behavior
controlsthe paging reference behavior of a specified range in a given map.This value changes how pageins are clustered. Possible values are VM_BEHAVIOR_DEFAULT
, VM_BEHAVIOR_RANDOM
, VM_BEHAVIOR_SEQUENTIAL
,and VM_BEHAVIOR_RSEQNTL
,for default, random, sequential, or reverse-sequential pagein ordering.protection
and max_protection
fieldscontrol the permissions on the object. The protection
fieldindicates what rights the task currently has for the object, whilethe max_protection
fieldcontains the maximum access that the current task can obtain forthe object.protection
fieldwhen debugging shared memory. By setting the protection to be read-only,any inadvertent writes to the shared memory would cause an exception.However, when the task actually needs to write to that shared region,it could increase its permissions in the protection
fieldto allow writes.max_protection
.protection
and max_protection
aredescribed in detail in xnu/osfmk/mach/vm_prot.h
.use_pmap
fieldindicates whether a submap’s low-level mappings should be sharedamong all tasks into which the submap is mapped. If the mappingsare not shared, then the structure of the map is shared among alltasks, but the actual contents of the pages are not.use_pmap
setto true. The read-write (nonshared) section has use_pmap
setto false, forcing a clean copy of the library’s DATA
segmentto be mapped in from disk for each new task.vm_allocate
toallocate memory in your address space and then calling mach_make_memory_entry_64
toget a handle to the underlying VM object.mach_make_memory_entry_64
canbe passed to vm_map
tomap that object into a given task’s address space. The handlecan also be passed via IPC or other means to other tasks so thatthey can map it into their address spaces. This provides the abilityto share objects with tasks that are not in your direct lineage,and also allows you to share additional memory with tasks in yourdirect lineage after those tasks are created.vm_region_object_create
.osfmk/mach/memory_object_types.h
.ubc_upl_commit
or ubc_upl_abort
,respectively.vm_object_upl_request
toget a UPL for that object. Otherwise, you must use the vm_map_get_upl
call.In either case, you are left with a handle to the UPL.UPL_CLEAN_IN_PLACE
existsto allow a page to be flushed to disk but not removed from memory.RETURN_ONLY_DIRTY
flag. Itcan also request all pages that are not in memory using the RETURN_ONLY_ABSENT
flag.BUSY
in the UPL, arequest for information on that page would normally block. If thepager is doing prefetching or preflushing, this is not desirable,since it might be blocking on itself or on some other pager thatis blocked waiting for the current transaction to complete. To avoidsuch deadlock, the UPL mechanism provides the UPL_NOBLOCK
flag.This is frequently used in the anonymous pager for requesting freememory.QUERY_OBJECT_TYPE
canbe used to determine if an object is physically contiguous and toget other properties of the underlying object.UPL_PRECIOUS
meansthat there should be only one copy of the data. This prevents havinga copy both in memory and in the backing store. However, this breaksthe adjacency of adjacent pages in the backing store, and is thusgenerally not used to avoid a performance hit.SET_INTERNAL
isused by the BSD subsystem to cause all information about a UPL tobe contained in a single memory object so that it can be passedaround more easily. It can only be used if your code is runningin the kernel’s address space.upl_commit_range
and upl_abort_range
,respectively.upl_commit_range
and upl_abort_range
callshave a flag that causes the UPL to be freed when there are no unmodifiedpages in the UPL. If you use this flag, you must be very carefulnot to use the UPL after all ranges have been committed or aborted.vm_map_get_upl
isfrequently used in file systems. It gets the underlying VM objectassociated with a given range within an address space. Since this returnsonly the first object in that range, it is your responsibility todetermine whether the entire range is covered by the resulting UPLand, if not, to make additional calls to get UPLs for other objects.Note that while the vm_map_get_upl
callis against an address space range, most UPL callsare against a vm_object
.sysctl
ora Mach RPC handler. In nearly all cases, convenient wrappers providethe needed functionality, however.vm_offset_t
type, which is a pointer-sized integer. In effect, you can think of them as pointers, with the caveat that they are not necessarily pointers to data in the kernel’s address space, depending on usage.vm_map_copyin
copiesdata from an arbitrary (potentially non–kernel) memory map intoa copy list and returns the copy list pointer in copy_result
.If something goes wrong and you need to throw away this intermediateobject, it should be freed with vm_map_copy_discard
.vm_map_copy_overwrite
. This overwritesan object with the contents of a copy list. For most purposes, thevalue passed for interruptible
should be FALSE
,and pmap
should be NULL
.kernel_map
to vm_map_copyin
andpass the user map to vm_map_copy_overwrite
.In general, however, you should avoid doing this, since you could endup with a task’s memory being fragmented into lots of tiny objects,which is undesirable.vm_map_copyout
whencopying data into an existing user task’s address map. The function vm_map_copyout
isused for filling an unused region in an address map. If the regionis allocated, then vm_map_copyout
doesnothing. Because it requires knowledge of the current state of themap, it is primarily used when creating a new address map (for example,if you are manually creating a new process). For most purposes,you do not need to use vm_map_copyout
.vm_map_wire
and vm_map_unwire
canbe used to wire and unwire portions of an address map. If you setthe argument user_wire
to TRUE
,then the page can be unwired from user space. This should be setto FALSE
if you are aboutto use the memory for I/O or for some other operation that cannottolerate paging. In vm_map_wire
,the argument access_type
indicatesthe types of accesses that should not be allowed to generate a page fault.In general, however, you should be using vm_wire
towire memory./var/vm/app_profile
andare only accessible by the super-user (and the kernel).pmap
entries.The read-write portions share a common submap, but have differentunderlying data objects (achieved through copy-on-write).dyld
.Do not use them in your programs.load_shared_file
isused to load a new shared library into the system. Once such a fileis loaded, other tasks can then depend on it, so a shared librarycannot be unshared. However, a new set of shared regions can becreated with new_system_shared_regions
sothat no new tasks will use old libraries.reset_shared_file
canbe used to reset any changes that your task may have made to itsprivate copy of the data section for a file.new_system_shared_regions
canbe used to create a new set of shared regions for future tasks.New regions can be used when updating prebinding with new sharedlibraries to cause new tasks to see the latest libraries at theirnew locations in memory. (Users of old shared libraries will stillwork, but they will fall off the pre-bound path and will performless efficiently.) It can also be used when dealing with private librariesthat you want to share only with your task’s descendents.IOMemoryDescriptor
changespmap
)changesIOMemoryDescriptor
ChangesIOMemoryDescriptor
::
prepare
,a mapping is automatically injected into the DART. When it calls IOMemoryDescriptor
::
release
,the mapping is removed. If you fail to do this, your driver couldexperience random data corruption or panics.pmap
Changes: pmap
layerhave no useful purpose outside the VM system itself. To preventtheir inadvertent use in device drivers, the pmap
callsare no longer available from kernel extensions.IOMemoryDescriptor
classstill use pmap
callsto get the physical pages associated with a virtual address. Also,a few developers have looked at the IOMemoryDescriptor
implementationand chosen to obtain addresses directly from the pmap
layer to remove what was perceived as an unnecessary abstraction layer.pmap
calls,these drivers would not function on systems with a DART (see thePCI section above for info on DARTs). To better emphasize this upcomingfailure, Panther will cause these drivers to fail to load with anundefined symbol error (generally for pmap_extract
)even on systems without a DART.<libkern/OSMalloc.h>
header defines the following routines for kernel memory allocation:OSMalloc
—allocates a block of memory.OSMalloc_noblock
—allocates a block of memory, but immediately returns NULL if the request would block.OSMalloc_nowait
—same as OSMalloc_noblock
.OSFree
—releases memory allocated with any of the OSMalloc
variants.OSMalloc_Tagalloc
—allows you to create a unique tag for your memory allocations. You must
create at least one tag before you can use any of the OSMalloc
functions.OSMalloc_Tagfree
—releases a tag allocated with OSMalloc_Tagalloc. (You must release all allocations associated with that tag before you call this function.)OSMT_PAGEABLE
instead of OSMT_DEFAULT
in your call to OSMalloc_Tagalloc
.IOMallocContiguous
and IOMallocAligned
differ somewhat from their Mach underpinnings. IOMallocAligned
uses calls directly to Mach VM to add support for arbitrary (power of 2) data alignment, rather than aligning based on the size of the object. IOMallocContiguous
adds an additional parameter, PhysicalAddress
. If this pointer is not NULL
, the physical address is returned through this pointer. Using Mach functions, obtaining the physical address requires a separate function call.IOMemoryDescriptor
or IOBufferMemoryDescriptor
and specify that the buffer should be sharable. If you are allocating memory in a user application that will be shared with the kernel, you should use valloc
or vm_allocate
instead of malloc
and then call mach_make_memory_entry_64
._MALLOC
and _FREE
, which may be used in BSD parts of the kernel.vm_offset_t
type, which is a pointer-sized integer. In effect, you can think of them as pointers, with the caveat that they are not necessarily pointers to data in the kernel’s address space, depending on usage.kernel_map
forthis argument.kmem_alloc
functionsexcept kmem_alloc_pageable
allocatewired memory. The function kmem_alloc_pageable
createsthe appropriate VM structures but does not back the region withphysical memory. This function could be combined with vm_map_copyout
when creatinga new address map, for example. In practice, it is rarely used.kmem_alloc_aligned
allocatesmemory aligned according to the value of the size
argument,which must be a power of 2.kmem_alloc_wired
issynonymous with kmem_alloc
andis appropriate for data structures that cannot be paged out. Itis not strictly necessary; however, if you explicitly need certainpieces of data to be wired, using kmem_alloc_wired
makesit easier to find those portions of your code.kmem_alloc_contig
attemptsto allocate a block of physically contiguous memory. This is notalways possible, and requires a full sort of the system free listeven for short allocations. After startup, this sort can cause longdelays, particularly on systems with lots of RAM. You should generallynot use this function.kmem_free
isused to free an object allocated with one of the kmem_alloc
functions.Unlike the standard C free
function, kmem_free
requiresthe length of the object. If you are not allocating fixed-size objects(for example, sizeof struct foo
),you may have to do some additional bookkeeping, since you must freean entire object, not just a portion of one.