Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

ユーザーアドレス

ユーザースレッドが write(2) システムコールを発行する場合、そのスレッドはユーザー空間内のバッファーのアドレスを渡します。

char buffer[] = "python";
count = write(fd, buffer, strlen(buffer) + 1);

システムは、iovec(9S) 構造体を割り当て、iov_base フィールドを write(2) に渡されたアドレス (この場合は、buffer) に設定することによって、この転送を記述する uio(9S) 構造体を構築します。この uio(9S) 構造体は、ドライバの write(9E) ルーチンに渡されます。uio(9S) 構造体の詳細については、Vectored I/Oを参照してください。

iovec(9S) 内のアドレスはカーネル空間ではなく、ユーザー空間内にあります。そのため、このアドレスは現在メモリー内に存在することも、有効なアドレスであることも保証されません。いずれの場合も、デバイスドライバまたはカーネルから直接ユーザーアドレスにアクセスすると、システムがクラッシュする可能性があります。そのため、デバイスドライバは、直接ユーザーアドレスにアクセスしてはいけません。代わりに、Oracle Solaris DDI/DKI にあるデータ転送ルーチンを使用してカーネルとの間のデータ転送を行うべきです。これらのルーチンは、ページフォルトを処理できます。DDI/DKI のルーチンは、コピーを透過的に続行するための適切なユーザーページを取得できます。あるいは、無効なアクセスに対してエラーを返すこともできます。

copyout(9F) を使用すると、カーネル空間からユーザー空間にデータをコピーできます。copyin (9F) は、ユーザー空間からカーネル空間にデータをコピーできます。 ddi_copyout(9F) ddi_copyin(9F) も同様に動作しますが、ioctl (9E) ルーチンで使用されることを想定しています。copyin (9F)copyout (9F) は、各 iovec(9S) 構造体で記述されたバッファーに対して使用できます。または、 uiomove(9F) は、隣接するドライバの領域またはデバイスメモリーとの間の転送全体を実行できます。