Q:
I/O Kit カーネルドライバでメモリを割り当てた後、それを IOMemoryDescriptor::map を使ってユーザ空間にマップしています。Mac OS X の以前のバージョンではこの処理がうまく行っていたのですが、10.2 では map が NULL を戻すようになりました。どのような変更があり、解決するのかを教えてください。
A:
IOMemoryDescriptor::map は要求されたとおりにバッファをマップできないと NULL を戻します。
以下に、Mac OS X 10.2 でこれが変更された背景を説明します。I/O Kit は、その malloc 用の小さなリソースとして、カーネル zalloc プールを使います。これにより、ドライバ作成者は、ローカルで使用するメモリをすばやく割り当てることができます。これは、new 演算子と、存続期間が極端に短いバッファにとっては非常に重要です。問題は、ドライバ作成者が、ゾーンアロケータの用途は一時的でごくプライベートな割り当て用であることを忘れて、メモリをユーザ空間と共有しようとしたときに起こります。
裏側では、IOMalloc、IOMallocAligned、IOMallocContiguous などの I/O Kit アロケータは、このゾーンアロケータを使用して、使用頻度が高く小さなメモリの割り当て処理の効率を向上させています。しかし、IOMallocAligned または IOMallocContiguous を使用して、少なくとも 1 つの完全なページを要求した場合、これらのインタフェースはどちらも共有可能なバッファを戻します。ページのサイズはハードコードしてはなりません。代わりに、カーネルのグローバル変数 page_size を使用する必要があります。最終的に共有するつもりのメモリを取得する場合、IOMalloc は使用しないでください。
それよりもよいのは、IOBufferMemoryDescriptor を使用して、バッファとメモリ記述子を一緒に割り当てるという方法です。この関数は、リスト 1 に示すように、バッファの割り当てを処理します。
|