|
|
< Previous PageNext Page > |
As with most things in the Mac OS X kernel, there are a number of ways to allocate memory. The choice of routines depends both on the location of the calling routine and on the reason for allocating memory. In general, you should use Mach routines for allocating memory unless you are writing code for use in the I/O Kit, in which case you should use I/O Kit routines.
Allocating Memory Using Mach Routines
Allocating Memory From the I/O Kit
Mach routines provide a relatively straightforward interface
for allocating and releasing memory. They are the preferred mechanism
for allocating memory outside of the I/O Kit. BSD also offers _MALLOC
and _FREE
,
which may be used in BSD parts of the kernel.
They do not provide for forced mapping of a given physical address to a virtual address. However, if you need such a mapping, you are probably writing a device driver, in which case you should be using I/O Kit routines instead of Mach routines.
These are some of the commonly used Mach routines for allocating memory:
kern_return_t kmem_alloc(vm_map_t map, vm_offset_t *addrp, vm_size_t size); |
void kmem_free(vm_map_t map, vm_offset_t addr, vm_size_t size); |
kern_return_t mem_alloc_aligned(vm_map_t map, vm_offset_t *addrp, |
vm_size_t size); |
kern_return_t kmem_alloc_wired(vm_map_t map, vm_offset_t *addrp, |
vm_size_t size); |
kern_return_t kmem_alloc_pageable(vm_map_t map, vm_offset_t *addrp, |
vm_size_t size); |
kern_return_t kmem_alloc_contig(vm_map_t map, vm_offset_t *addrp, |
vm_size_t size, vm_offset_t mask, int flags); |
These functions all take a map as the first argument. Unless
you need to allocate memory in a different map, you should pass kernel_map
for
this argument.
All of the kmem_alloc
functions
except kmem_alloc_pageable
allocate
wired memory. The function kmem_alloc_pageable
creates
the appropriate VM structures but does not back the region with
physical memory. This function could be combined with vm_map_copyout
when creating
a new address map, for example. In practice, it is rarely used.
The function kmem_alloc_aligned
allocates
memory aligned according to the value of the size
argument,
which must be a power of 2.
The function kmem_alloc_wired
is
synonymous with kmem_alloc
and
is appropriate for data structures that cannot be paged out. It
is not strictly necessary; however, if you explicitly need certain
pieces of data to be wired, using kmem_alloc_wired
makes
it easier to find those portions of your code.
The function kmem_alloc_contig
attempts
to allocate a block of physically contiguous memory. This is not
always possible, and requires a full sort of the system free list
even for short allocations. After startup, this sort can cause long
delays, particularly on systems with lots of RAM. You should generally
not use this function.
The function kmem_free
is
used to free an object allocated with one of the kmem_alloc
functions.
Unlike the standard C free
function, kmem_free
requires
the 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 free
an entire object, not just a portion of one.
Although the I/O Kit is generally beyond the scope of this document, the I/O Kit memory management routines are presented here for completeness. In general, I/O Kit routines should not be used outside the I/O Kit. Similarly, Mach allocation routines should not be directly used from the I/O Kit because the I/O Kit has abstractions for those routines that fit the I/O Kit development model more closely.
The I/O Kit includes the following routines for kernel memory allocation:
void *IOMalloc(vm_size_t size); |
void *IOMallocAligned(vm_size_t size, vm_size_t alignment); |
void *IOMallocContiguous(vm_size_t size, vm_size_t alignment, |
IOPhysicalAddress *physicalAddress); |
void *IOMallocPageable(vm_size_t size, vm_size_t alignment); |
void IOFree(void *address, vm_size_t size); |
void IOFreeAligned(void *address, vm_size_t size); |
void IOFreeContiguous(void *address, vm_size_t size); |
void IOFreePageable(void *address, vm_size_t size); |
Most of these routines are relatively transparent wrappers around the Mach allocation functions. There are two major differences, however. First, the caller does not need to know which memory map is being modified. Second, they have a separate free call for each allocation call for internal bookkeeping reasons.
The functions 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.
Important:
If your KEXT allocates memory that will be shared,
you should create a buffer of type 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
.
< Previous PageNext Page > |
Last updated: 2006-11-07
|
Get information on Apple products.
Visit the Apple Store online or at retail locations. 1-800-MY-APPLE Copyright © 2007 Apple Inc. All rights reserved. | Terms of use | Privacy Notice |