使用 ddi_umem_alloc(9F) 可以分配导出到应用程序的内核内存。 ddi_umem_alloc() 的语法如下所示:
void *ddi_umem_alloc(size_t size, int flag, ddi_umem_cookie_t *cookiep);
其中:
要分配的字节数。
用于确定休眠条件和内存类型。
指向内核内存 cookie 的指针。
ddi_umem_alloc(9F) 分配按页对齐的内核内存。ddi_umem_alloc () 返回一个指向所分配内存的指针。最初,内存被零填充。分配的字节数是系统页面大小的倍数,该页面大小是通过 size 参数向上舍入得到的。分配的内存可在内核中使用。此内存也可导出到应用程序。cookiep 是指向用来描述所分配的内核内存的内核内存 cookie 的指针。驱动程序将内核内存导出到用户应用程序时,devmap_umem_setup(9F) 中会使用 cookiep。
flag 参数用于指示 ddi_umem_alloc(9F) 是立即阻塞还是返回,以及分配的内核内存是否可换页。flag 参数的值如下所示:
驱动程序无需等待内存成为可用。如果内存不可用,则返回 NULL。
驱动程序可以无限等待,直到内存可用为止。
驱动程序允许内存页被换出。如果未设置,则锁定内存。
ddi_umem_lock() 函数可以执行设备锁定内存检查。此函数针对 project.max-locked-memory 中指定的限制值进行检查。如果当前项目的锁定内存使用量低于限制,则会增加项目的锁定内存字节计数。进行限制检查后,内存将会锁定。ddi_umem_unlock() 函数可以解除锁定内存,从而减少项目的锁定内存字节计数。
其中所用的记帐方法是不严密的 "full price"(足价)模式。例如,对于同一项目中 umem_lockmemory() 的具有重叠内存区域的两个调用程序会被计数两次。
有关 project.max-locked-memory 和 zone.max-locked_memory 对安装了区域的 Solaris 系统的资源控制的信息,请参见《Solaris 10 资源管理器开发者指南》和 resource_controls(5)。
以下示例说明如何为应用程序访问分配内核内存。驱动程序会导出一页内核内存,它将被多个应用程序用作共享存储区。应用程序第一次映射共享页时,会在 segmap(9E) 中分配内存。如果驱动程序必须支持多个应用程序数据模型,则会再分配一页。例如,64 位驱动程序可能同时将内存导出到 64 位应用程序和 32 位应用程序。64 位应用程序共享第一页,32 位应用程序共享第二页。
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); size_t mem_size; /* 64-bit driver supports 64-bit and 32-bit applications */ switch (ddi_mmap_get_model()) { case DDI_MODEL_LP64: mem_size = ptob(2); break; case DDI_MODEL_ILP32: mem_size = ptob(1); break; } mutex_enter(&xsp->mu); if (xsp->umem == NULL) { /* allocate the shared area as kernel pageable memory */ xsp->umem = ddi_umem_alloc(mem_size, DDI_UMEM_SLEEP | DDI_UMEM_PAGEABLE, &xsp->ucookie); } mutex_exit(&xsp->mu); /* Set up the user mapping */ error = devmap_setup(dev, (offset_t)off, asp, addrp, len, prot, maxprot, flags, credp); return (error); }