PCIeカードを搭載したLinuxボックスへの高速データ転送には、高速シリアルカードを使用しています。 PCIeカードには、データを受信するためにdma_alloc_coherentを使用してdmaバッファを割り当てるサードパーティのドライバが付属していました。しかしLinuxの制限により、この方法ではデータ転送が4MBに制限されます。私は大規模なDMAバッファを割り当てるための複数のメソッドを読み込み、試してきましたが、これを動作させることができませんでした。大規模PCIe DMA Linux x86-64
このシステムは32GBのメモリを搭載しており、カーネルバージョン3.10のRed Hatを実行しています。この4GBを連続DMA用に使用したいと考えています。私は優先メソッドが散布/収集であることを知っていますが、これは自分の状況では可能ではありません。ハードウェアチップがシリアルプロトコルを私の制御を超えたDMAに変換したからです。着信アドレス(すなわち、外部システムから見たアドレスゼロは、ローカルバス上のアドレス0x700000000にマッピングすることができる)。
これは単発ラボマシンなので、最も速く/最も簡単なアプローチは、mem = 28GBのブート設定パラメータを使用することです。私はこれはうまく動作しますが、仮想空間からそのメモリにアクセスする次のステップは、私が問題を抱えているところです。カーネルモジュールで
:アプリケーションで
size_t len = 0x100000000ULL; // 4GB
size_t phys = 0x700000000ULL; // 28GB
size_t virt = ioremap_nocache(phys, len); // address not usable via direct reference
size_t bus = (size_t)virt_to_bus((void*)virt); // this should be the same as phys for x86-64, shouldn't it?
// OLD WAY
/*size_t len = 0x400000; // 4MB
size_t bus;
size_t virt = dma_alloc_coherent(devHandle, len, &bus, GFP_ATOMIC);
size_t phys = (size_t)virt_to_phys((void*)virt);*/
:ここに私のコードでは、関連するコンポーネントに凝縮され
もう一つ興味深いのは、このすべてを行う前に、物理的ですdma_alloc_coherentから返されたアドレスがシステム上のRAMの量(0x83d000000)より大きい。私はx86ではRAMは常に最低アドレスになると思っていたので、私は32GB未満のアドレスを期待していました。
ご協力いただければ幸いです。
Err ... '0x770000000ULL'は29.75 GBではなく28 ...代わりに' 0x700000000'を試してください。 –
ドープ、愚かな数学のエラー。その領域がまだ有効なRAMである必要があるので、問題はありません。私はまだ4GBのテストケースには行かず、まだ4MBしか使用していませんでした。質問が更新されます。 – LINEMAN78
私は32GBのメモリシステムを持っています。絶対ベアボーンを掲示しても、カーネルモジュールのソースファイルを完成させることができますか?テストする絶対最小usermodeプログラムですか?また、なぜ[C++]でタグ付けしたのですか?Linuxカーネルが[c]のみで、あなたが表示するusermodeスニペットがC APIだけを使用していますか? –