HDK Technical Reference

Memory allocation

The DDI and ODDI interfaces each provide several functions for allocating private memory for a driver. The differences between the functions concern the properties of the memory that is allocated and when the memory is allocated. Drivers allocate some memory that is only accessed by the kernel itself and other memory that is accessed by both the kernel and the device.

physical alignment
Some operations require specific alignment properties, such as needing to aligned on a page boundary.

zeroed out memory
The memory that is allocated may have been used previously and contain data. Such memory can be zeroed out after it is allocated, but it is more efficient to use a memory allocation function that zeroes out the allocated memory as part of the allocation.

context for allocation
Some restrictions apply to the context in which memory is allocated. This is a special concern when memory must be allocated from initialization or interrupt context; see ``Context of a driver''.

device requirements
Memory accessed directly by devices for I/O operations may have special physical requirements such as memory range, contiguity, and granularity. These issues are discussed in the articles about the specific I/O strategies: ``DMA'', ``Memory-mapped I/O'', ``Programmed I/O (PIO)''.

Kernel memory is a limited resource and should be used judiciously. The following guidelines apply to memory allocation:

DDI implementation

Three main structures are used with DDI functions that allocate memory and need to specify special properties for that memory:

Breakup control block, passed to the buf_breakup(D3) function to control parceling the data to be transferred through a scatter/gather scheme.

Structure that defines physical address alignment and contiguity constraints for memory to be allocated.

scgth(D4) (DDI 8 and later only)
Describes the scatter/gather list.
The following functions are supported for allocating memory in DDI drivers. Check the manual pages for version-specific information.

Allocate memory in the physical address range 0,0x10000000 that is physically contiguous only if the allocation size is less than or equal to one page, given by ptob(D3). Physical alignment is to the next highest power of 2 from the allocation size, but not greater than 1 page.

kmem_alloc_phys(D3) (DDI 8 and later)
Allocate physical-contiguous memory based on the properties specified in a physreq(D4) structure. kmem_alloc_phys( ) returns a 32-bit physical address.

kmem_alloc_physreq(D3) (DDI 6 and later)
Allocate physically-contiguous memory, based on the properties specified in a physreq(D4) structure. kmem_alloc_physreq( ) returns a virtual memory address that is translated to a physical address with the vtop(D3) function.

Free memory allocated with the kmem_alloc( ), kmem_alloc_phys( ), kmem_alloc_physreq( ), kmem_zalloc( ), or kmem_zalloc_physreq( ) functions.

Allocate physically contiguous memory (DDI 5 and 6 only).

Free memory allocated with the kmem_alloc_physcontig(D3) function.

Similar to kmem_alloc( ), but the allocated memory is cleared as part of the allocation.

Similar to kmem_alloc_physreq( ), but the allocated memory is cleared as part of the allocation.

Allocate a physreq structure.

Prepare a physreq structure for use. This function must be called after the physreq structure is allocated and all necessary members have been set, but before the structure is passed to any I/O or memory allocation function.

Free a physreq structure.

Allocate and initialize a private space management map.

Allocate space from a private space management map.

Identical to rmalloc( ), except that the allocation will block to wait for resources if necessary.

Return memory to the private space management map.

Free a private space management map.

rminit(D3) (DDI 1, 2, 4 only)
Free a private space management map. Use rmallocmap(D3) for current DDI versions.

rmsetwant(D3) (DDI 1, 2, 4 only)
Set the map's wait flag for a wakeup. Use rmalloc_wait(D3) for current DDI versions.

Note that DDI versions prior to version 5 do not support functions that use the physreq(D4) structure. Non-DDI functions such as getcpages( ) and freepages( ) were available for allocating physically contiguous memory but these should not be used in current drivers.

ODDI implementation

ODDI drivers on SCO OpenServer 5 use the following functions to allocate memory:

Allocate extents of kernel memory. Flags specify whether or not the allocated memory is DMA-able and the contexts in which this function can be called.

Similar to kmem_alloc( ), but the allocated memory is cleared as part of the allocation.

Free memory allocated with the kmem_alloc( ) or kmem_zalloc( ) function.

Allocate contiguous memory from an init(D2oddi) routine.

Allocate memory that can be used by any process or for mapping in memory from a device.

Free memory allocated with sptalloc( ).

Allocate contiguous pages of memory.

Free memory allocated with getcpages( ).

SCO OpenServer 5 also retains support for older mechanisms for memory allocation. These are not generally used in new drivers but are used in some older drivers that are supported:

Allocate DMAable memory that can be read from and written to with the db_read(D3oddi) and db_write(D3oddi) functions.

Free memory allocated with db_alloc(D3oddi).

Allocate virtual memory.

Map non-DMA-able memory that can be used only by a specific process.

Determine if mapping is already in place.

Undo a vasbind( ) mapping.

Allocating STREAMS memory

STREAMS drivers use the standard DDI and ODDI functions to allocate memory for general purposes. The following supplement these functions to allocate message blocks for STREAMS and MDI drivers:

allocate a STREAMS message block

allocb_physreq(D3str) (DDI 6 and later)
allocate a STREAMS message block that is DMA-able or satisfies other physical requirements such as starting address alignment or physical address range.

allocate a STREAMS message block by using an externally-supplied buffer.

align bytes for a message to satisfy physical DMA requirements.

msgscgth(D3str) (DDI 8 and later)
construct a DMA scatter/gather list for a message block.

See ``Messages, STREAMS'' for general information about allocating STREAMS message blocks.

See ``Message block allocation'' for guidelines about allocating STREAMS message blocks.

SDI implementation

SDI drivers use the sdi_kmem_alloc_phys(D3sdi) function to allocate memory that will be passed to the target device. The memory allocated is defined with a physreq(D4) structure and can be DMA addressable and device accessible memory. All other memory allocation is done with the standard DDI memory allocation functions such as kmem_alloc( ).

© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005