いくつかのメモリ マップ ハードウェア用の Linux ドライバーを作成する予定です (FPGA 内にあるため、必要に応じて両端でこのメモリ マップ インターフェイスを調整できます)。
この FPGA ロジックは、一連のデータグラムを生成します。これを処理してから、イーサネット リンクを介して送信する必要があります。処理またはネットワーク コードのいずれかがカーネルにある理由はないので、データのブロックをハードウェアからユーザー空間に移動するための「最良の」メカニズムについて質問しています。最大の複雑さは、ユーザー空間の処理を複数のプロセスに分散する必要があることです。
データレートはそれほど高くなく (最大 1Mbps)、mmio インターフェイスはかなり深い FIFO (現在は 2KB、最大 8KB まで増やすことができます) によって供給されるため、優先度の高いユーザーモードプロセスが追いつくことができると思います。
私が本当に欲しいのは、既存のマルチキャスト ユーザー空間インターフェイスを備えた既存のドライバーへのポインターです (それ以外はそれほど複雑ではありません)。しかし、何をしなければならないかの概要は、合理的な代用になるでしょう。
これまでに次のアイデアを収集しました。
AF_NETLINK: マルチキャストをサポートし、バッファリングを処理します。しかし、API は不安定で、他のインツリー ドライバーと競合する可能性のある新しいソケット ID を定義する必要があり、ユーザー モード インターフェイスは非常に特殊化
socat
されており、データ ストリームのテストなどの標準ツールを使用することはできません。ユーザー空間からデータグラムモードのソケットまたは FIFO ファイル記述子を渡し、それに書き込みます (どのように?)。私が適用できる unix ドメイン データグラム ソケット マルチキャスト パッチがあります。
キャラクター モード デバイスを単一の優先度の高いユーザー モード アプリケーションに公開します。このアプリケーションは、UNIX ドメイン データグラム ソケット サーバーとして機能し、接続されている各ノードにデータグラムをコピーします。キャラクタ モード デバイスのデータグラム境界は維持されますか (つまり、ドライバ関数がバッファ サイズ
read
よりも少ないバイト数を返す場合、そのデータ ブロックを 1 つのユニットとして返すか、ブロックをフラグメント化して再構築できますか?の代わりに?ドライバーの読み取り関数がデータグラムが切り捨てられたことを示すために使用できるようなものはありますか、それともソケットでのみ使用できますか?)fread
fread
read (2)
fread (3)
EMSGSIZE
複数のユーザー モード アプリケーションで同時に開くことができるキャラクター モード デバイスを公開し、データを各カーネル内にバッファーします。
私は、着信パケットを再ルーティングする UNIX ドメインサーバーを備えたキャラクターモードデバイスに傾いています。これにより、カーネル ドライバー内にバッファリング ロジックを実装する必要がなくなりました。select
問題は、割り込みが発生したときに呼び出しまたはブロック読み取りからユーザープロセスをウェイクアップする方法です。私のpoll
関数は、制御レジスタを読み取って、POLLIN|POLLRDNORM
データが既に利用可能な場合は戻り、そうでない場合は割り込みのマスクを解除できるようです。そして、割り込みハンドラーは、準備完了 wake_up
のフラグを立てるために使用します。常に割り込みをマスクします。wait_queue
read