ストリーミングDMA API(すなわち、dma_map_*()
/dma_unmap_*()
)では、実際には何も再マッピングされません。カーネル・リニア・マッピング(すなわち、通常のkmalloc()
メモリ)からのアドレスのみがストリーミングDMAに対して有効であるため、CPUマッピングがキャッシュ可能であるため、非コヒーレント・デバイスに対するdma_map_*()
オペレーションは、バッファのエクステントに応じてキャッシュをクリーニング/対応するdma_unmap_*()
までそれにアクセスしていないCPUに頼ってください。その後、CPUがデバイスによってメモリに書き込まれたデータを読み取る前に、投機的なフェッチがあった場合に、キャッシュを再び無効にする(適切な場合)。キャッシュコヒーレントデバイスの場合は、そのどれも必要ではないので、スキップします。
バッファがリニアマップになっているため、DMAアドレスはオフセットの単純な場合を除いて、ファンキーなハードウェアの特定のケースで物理メモリとバスアドレスを変換するデバイス固有のオフセットを除いたものです(例:Raspberry Pi 2/3またはTI Keystone 2) - たとえばthe ARM implementation of dma_map_page()
(そのうちdma_map_single()
is merely a special case)。 IOMMUが関与している場合、その物理アドレスのIOVAマッピングを作成し、基礎となるバスアドレスの代わりにそのIOVAを返す追加のステップがあります。 コヒーレント DMAのAPI(すなわちdma_alloc_coherent()
)のためにその
注意、デバイスはキャッシュコヒーレントそのものではないとき、私たちはを使用し、その後、vmalloc領域内の割り当てられたページの別の非キャッシュ可能マッピングを作成しますストリーミングDMAとは異なり、CPUとデバイスの両方がいつでもコヒーレントバッファにアクセスすることができるため、そのバッファへのすべてのCPUアクセスに対する非キャッシュ可能なエイリアス(リニアマップエイリアスをクリーニングするための初期キャッシュメンテナンス後)
ありがとう、これは多くを明確にします。コードをチェックしたところ、pfn_to_busはあなたが言ったようにpfnを物理アドレスに変換しますが、バスオフセットが適用されているのを見ることはできません。 #define __pfn_to_bus(x)__pfn_to_phys(x)。何か不足していますか? – shunty
あなたが欲しい@shunty [ 'pfn_to_dma()'](http://lxr.free-electrons.com/source/arch/arm/include/asm/dma-mapping.h?v4.7#L54)。 – Notlikethat
'pfn - = dev-> dma_pfn_offset;'このdma_pfn_offsetはデバイス固有のものですか?デバイスのコンフィギュレーション中に初期化されますか? – shunty