8

dma_map_singleパラメータとして渡されたバッファを使用したLDD3 (p:453) のデモ。

bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, dev->dma_dir);

Q1 : このバッファーはどこから来たのですか?

kmalloc?

Q2 : DMA-API-HOWTO.txt に rawkmallocを DMA に使用できると記載されているのはなぜですか?

フォームhttp://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt

L:51 ページ アロケータ kmalloc() を介してメモリを取得した場合は、これらのルーチンから返されたアドレスを使用して、そのメモリとの間で DMA を実行できます。

L:74 kmap() 呼び出しと DMA のリターンを取得することはできません。

  1. から返されたアドレスkmallocをハードウェアデバイスに渡すことができますか?
  2. それとも最初に実行する必要がありvirt_to_busますか?
  3. または、これをに渡す必要がありdma_map_singleますか?

Q3 : DMA 転送が完了したら、アドレス経由でカーネル ドライバのデータを読み取ることはできkmallocますか?

addr = kmalloc(...);
...
printk("test result : 0x%08x\n", addr[0]);

Q4 : これをユーザー空間に移動する最良の方法は何ですか?

  1. copy_to_user?
  2. kmallocメモリをmmapしますか?
  3. 他?
4

1 に答える 1

16
  1. kmalloc は実際にバッファを取得するための 1 つのソースです。もう 1 つは、GFP_DMA フラグを指定した alloc_page です。

  2. つまり、kmalloc が返すメモリは、仮想メモリだけでなく、物理メモリでも連続していることが保証されているため、そのポインタのバス アドレスをハードウェアに与えることができます。返されたアドレスで dma_map_single() を使用する必要がありますが、正確なプラットフォームによっては、virt_to_bus のラッパーではないか、それ以上のことを行う可能性があります (IOMMU または GART テーブルをセットアップします)。

  3. 正解です。DMA ガイドで説明されているように、キャッシュ コヒーレンシのガイドラインに従ってください。

  4. copy_to_user は問題なく動作し、最も簡単な答えです。特定のケースに応じて、それで十分な場合もあれば、より優れたパフォーマンスのものが必要な場合もあります。通常、kmalloced アドレスをユーザー空間にマップすることはできませんが、ユーザーが指定したアドレスに DMA (いくつかの注意事項が適用されます) またはユーザー ページを割り当てることができます (alloc_page with GFP_USER)。

幸運を!

于 2011-04-06T11:57:08.613 に答える