ホームページ >コンピューターのチュートリアル >トラブルシューティング >DMA Windows ドライバーのソース コードはありますか?

DMA Windows ドライバーのソース コードはありますか?

PHPz
PHPz転載
2024-01-18 08:30:16611ブラウズ

dma windows驱动源码吗?

DMA の関連操作については、「Linux カーネルの徹底理解」の 545 ページで紹介されています。 DMA について話すときは、キャッシュの問題について言及する必要があります。この本では、キャッシュの一貫性の問題を説明するために次の例を引用しています。

デバイス ドライバーが一部のデータをメモリ バッファーに書き込み、すぐに DMA 転送を使用してデータを読み取るようにハードウェア デバイスに指示すると仮定します。 DMA がこれらの物理 RAM メモリ セルにアクセスし、対応するハードウェア キャッシュ ラインの内容がまだ RAM に書き込まれていない場合、ハードウェア デバイスはメモリ バッファ内の古い値のみを読み取ります。

現在、DMA バッファを扱う方法は 2 つあります。

一貫した DMA マッピング:

本書はより抽象的であり、一般的な用語は任意の DMA バッファです。領域はメモリに直接更新されます。これは、同期または整合性とも呼ばれます。

ストリーミング DMA マッピング:

個人的な理解によると、ここでのストリームは入力ストリームと出力ストリームです。バッファの読み取りや、DMA バッファの方向など、事前に DMA バッファの方向を指定する必要があります。書き込みバッファゾーン。非同期、非一貫性とも呼ばれますので、詳しくは下記をご覧ください。

x86 アーキテクチャでは、ハードウェア デバイス ドライバ自体がアクセスされたハードウェア キャッシュをスヌープするため、x86 アーキテクチャでは DMA 一貫性の問題は発生しません。 MIPS、SPARC、POWERPC (ARM を含む) などの他のアーキテクチャの場合は、ソフトウェアで DMA の一貫性を確保する必要があります。

上記 2 つのどちらを選択するかについては、本書に適切な提案があり、CPU と DMA プロセッサが予測できない方法でバッファにアクセスする場合は、一貫した DMA マッピング方法を強制的に使用する必要があります。 (ここでは、予測不可能です (いつバッファにアクセスするかを決定できないと理解されています)。また、一部のアーキテクチャでは一貫した DMA マッピングの処理が面倒で、システム パフォーマンスの低下につながる可能性があるため、ストリーミング DMA マッピング アプローチが望ましい場合もあります。 。

ストリーミング DMA の詳細な紹介は次のとおりです:

アクセスする必要があるバッファは、データ送信前にマッピングする必要があります (ここでのマッピングは、データを送信するためにいくつかの関数を呼び出す必要があることを意味します)バッファがストリーミング マップされるカーネル)、転送後にマップ解除されます。

ストリーミング DMA データ転送の開始は、次の手順に分かれています:

1. DMA バッファを割り当てます。

DMA デバイスが S/G (スキャッター/ギャザー) モードを使用しない場合、バッファーが物理的に連続していることを確認する必要があります。Linux カーネルには、連続メモリを割り当てるための 2 つの関数、kmalloc() と __get_free_pages があります。 ()。どちらの関数にも連続メモリの割り当てには最大値があり、kmallocはバイト単位で最大約64KB、__get_free_pages()はページ単位で最大2^次数まで割り当て可能です。順序パラメータ include/linux/Mmzone.h ファイル内の MAX_ORDER マクロによって決定されます (デフォルトの 2.6.18 カーネル バージョンでは、このマクロは 10 として定義されています。つまり、理論的には、__get_free_pages 関数は最大数まで適用できます) #2. ストリーミング マッピングを確立します。

DMA バッファへの読み取りおよび書き込みアクセスの後、DMA デバイス転送を開始する前に、dma_map_single() 関数を有効にして、ストリーミング マッピングを確立します。ストリーミング DMA マッピング. これら 2 つの関数はバッファを受け入れます 領域のリニア アドレスがパラメータとして使用され、対応するバス アドレスが返されます.

3. ストリーミング マッピングを解放します。転送が完了したら、マッピングを解放してから dma_unmap_single() 関数を呼び出す必要があります。

注:

(1)。キャッシュの一貫性の問題を回避するには、ドライバーは dma_sync_single_for_device(() を呼び出す必要があります)必要に応じて、RAM からデバイスへの DMA データ転送を開始する前に) 関数は、DMA バッファに対応するキャッシュ ラインをリフレッシュします。

(2). デバイス ドライバは、RAM からの DMA データ転送の前にメモリ バッファにアクセスできません。デバイスから RAM への接続は完了しましたが、必要に応じて、ドライバはバッファを読み取る前に dma_sync_single_for_cpu() 関数を呼び出して、対応するハードウェア キャッシュ ラインを無効にする必要があります。また、kmalloc の対応するリリース バッファである __get_free_pages を使用して実装されます。エリア関数は kfree で、__get_free_pages に対応するリリース バッファ関数は free_pages です。特に __get_free_pages に関連するいくつかのアプリケーションおよびリリース関数は次のとおりです:

アプリケーション関数:

alloc_pages(gfp_mask ,order) は、最初に割り当てられたページ フレーム記述子のアドレスを返します。割り当てが失敗した場合は NULL を返します。__get_free_pages(gfp_mask,order) は alloc_pages() に似ていますが、次のリニア アドレスを返します。最初に割り当てられたページ リニア アドレスに対応するページ フレーム番号を取得する必要がある場合は、virt_to_page(addr) マクロを呼び出してリニア アドレスを生成する必要があります リリース関数: __free_pages(page, order) ここでの主な強調点そのページはバッファのリニア先頭アドレスが解放されるページ フレーム番号です free_pages (page, order) この関数は __free_pages(page, order) に似ていますが、受け取るパラメータはリニア アドレス addr# です。解放される最初のページ フレームの ##。

以上がDMA Windows ドライバーのソース コードはありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はxtzjcz.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。