Advanced Search
Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page >

Allocating Memory in the Kernel

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.

In this section:

Allocating Memory Using Mach Routines
Allocating Memory From the I/O Kit


Allocating Memory Using Mach Routines

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.

Allocating Memory From the I/O Kit

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




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
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