カーネルメモリーをユーザーアプリケーションにエクスポートするには、devmap_umem_setup(9F) を使用します。devmap_umem_setup () は、ドライバの devmap (9E) エントリポイントから呼び出す必要があります。 devmap_umem_setup() の構文は次のとおりです。
int devmap_umem_setup(devmap_cookie_t handle, dev_info_t *dip, struct devmap_callback_ctl *callbackops, ddi_umem_cookie_t cookie, offset_t koff, size_t len, uint_t maxprot, uint_t flags, ddi_device_acc_attr_t *accattrp);
ここでは:
マッピングを記述するために使用される不透明な構造体。
デバイスの dev_info 構造体へのポインタ。
devmap_callback_ctl(9S) 構造体へのポインタ。
ddi_umem_alloc(9F) から返されたカーネルメモリー cookie。
cookie で指定されたカーネルメモリー内へのオフセット。
エクスポートされる長さ (バイト)。
エクスポートされるマッピングで使用可能な最大の保護を指定します。
DEVMAP_DEFAULTS に設定する必要があります。
ddi_device_acc_attr(9S) 構造体へのポインタ。
handle は、システムがマッピングの識別子として使用するデバイスマッピングハンドルです。handle は、 devmap(9E) エントリポイントから渡されます。 dip は、デバイスの dev_info 構造体へのポインタです。callbackops は、マッピングに関するユーザーイベントの通知をドライバが受け取れるようにします。カーネルメモリーのエクスポート時には、ほとんどのドライバで callbackops が NULL に設定されます。
koff および len は、ddi_umem_alloc (9F) によって割り当てられたカーネルメモリー内の範囲を指定します。この範囲は、devmap (9E) エントリポイントから渡されたオフセットの位置で、ユーザーのアプリケーションマッピングからアクセス可能となります。通常、ドライバは devmap(9E) のオフセットを devmap_umem_setup(9F) に直接渡します。このとき、mmap(2) から返されるアドレスは、ddi_umem_alloc(9F) から返されたカーネルアドレスにマップされます。koff と len は、ページ境界割り当てされる必要があります。
ドライバは maxprot を使用することで、エクスポートされるカーネルメモリー内の個々の領域ごとに保護を指定できます。たとえば、ある領域の書き込みアクセス権を許可しないようにするには、PROT_READ と PROT_USER のみを設定します。
次の例は、カーネルメモリーをアプリケーションにエクスポートする方法を示したものです。ドライバはまず、要求されたマッピングが、割り当てられたカーネルメモリー領域内に収まっているかチェックします。64 ビットドライバは、32 ビットアプリケーションからマッピング要求を受け取ると、その要求をカーネルメモリー領域の 2 枚目のページにリダイレクトします。このリダイレクトにより、同じデータモデルを使用してコンパイルされたアプリケーションのみが同一ページを共有するようになります。
使用例 10-5 devmap_umem_setup (9F) ルーチンstatic int xxdevmap(dev_t dev, devmap_cookie_t handle, offset_t off, size_t len, size_t *maplen, uint_t model) { struct xxstate *xsp; int error; /* round up len to a multiple of a page size */ len = ptob(btopr(len)); /* check if the requested range is ok */ if (off + len > ptob(1)) return (ENXIO); xsp = ddi_get_soft_state(statep, getminor(dev)); if (xsp == NULL) return (ENXIO); if (ddi_model_convert_from(model) == DDI_MODEL_ILP32) /* request from 32-bit application. Skip first page */ off += ptob(1); /* export the memory to the application */ error = devmap_umem_setup(handle, xsp->dip, NULL, xsp->ucookie, off, len, PROT_ALL, DEVMAP_DEFAULTS, NULL); *maplen = len; return (error); }