Writing Device Drivers

Allocating Kernel Memory for User Access

ddi_umem_alloc(9F) is provided to allocate kernel memory that is exported to applications:

	void *ddi_umem_alloc(size_t size, int flag,
 			ddi_umem_cookie_t *cookiep);			

size is the number of bytes to allocate.

flag is used to determine the sleep conditions and the memory type.

cookiep is a pointer to a kernel memory cookie.

ddi_umem_alloc(9F) allocates page-aligned kernel memory and returns a pointer to the allocated memory. The initial contents of the memory is zero-filled. The number of bytes allocated is a multiple of the system page size (roundup of size). The allocated memory can be used in the kernel and can be exported to applications. cookiep is a pointer to the kernel memory cookie that describes the kernel memory being allocated. It is used in devmap_umem_setup(9F) when the driver exports the kernel memory to a user application.

The flag argument indicates whether ddi_umem_alloc(9F) will block or return immediately, and whether the allocated kernel memory is pageable. Table 11-1 lists the values for flag.

Table 11-1 ddi_umem_alloc(9F) flag Values


Indicated Action 


Driver does not need to wait for memory to become available. Return NULL if memory unavailable. 


Driver can wait indefinitely for memory to become available. 


Driver allows memory to be paged out. If not set, the memory will be locked down. 

Example 11-2 shows how to allocate kernel memory for application access. The driver exports one page of kernel memory, which is used by multiple applications as a shared memory area. The memory is allocated in segmap(9E) when an application maps the shared page the first time. An additional page is allocated if the driver has to support multiple application data models (for example a 64-bit driver exporting memory to 64-bit and 32-bit applications). 64-bit applications share the first page, and 32-bit applications share the second page.

Example 11-2 ddi_umem_alloc(9F) Routine

static int
xxsegmap(dev_t dev, off_t off, struct as *asp, caddr_t *addrp,
	off_t len, unsigned int prot, unsigned int maxprot,
	unsigned int flags, cred_t *credp)
	int error;
	minor_t instance = getminor(dev);
	struct xxstate *xsp = ddi_get_soft_state(statep, instance);

	if (xsp->umem == NULL) {
	   	size_t mem_size;
		/* 64-bit driver supports 64-bit and 32-bit applications */
	   	mem_size = ptob(2);
	   	mem_size = ptob(1);
#endif /* _MULTI_DATAMODEL */

	   	/* allocate the shared area as kernel pageable memory */
	   	xsp->umem = ddi_umem_alloc(mem_size,
	/* Set up the user mapping */
	error = devmap_setup(dev, (offset_t)off, asp, addrp, len,
				prot, maxprot, flags, credp);
	return (error);