2017-09-12 22 views
2

キャラクタデバイスファイルを使用するデバイスドライバを作成して、mallocを使ってカーネルバッファに割り当てられたユーザスペースバッファからデータをコピーしています。現在copy_from_user apiを使用して、ユーザーデータをカーネルバッファにコピーします。ユーザーとカーネルの間のデータコピーを避ける方法を見つけようとしています。 copy_from_userを使用せずにカーネル空間のユーザ空間バッファ(mallocによって割り当てられた)にアクセスする方法はありますか?Linuxデバイスドライバでcopy_from_userとcopy_to_userを避ける方法

+3

「malloc」によって作成されたユーザスペースバッファにアクセスするために*あなたの質問が印象づけられているので、これを回答として投稿するべきかどうかはわかりません。しかし、そのような目標設定は有用ではないかもしれません。代わりに、ユーザ空間アプリケーションが 'mmap()'システムコールを使用してデバイスメモリの一部に直接アクセスする可能性があります。同時に、デバイスドライバは 'struct file_operations'の' mmap'コールバックを実装する必要があります。このアイデアが気に入ったら、LDD3の書籍(http://www.makelinux.net/ldd3/chp-15-sect-2)の広範な説明を参照してください。 –

+1

また、Linuxカーネルには、文字デバイスの例ではない 'PACKET_MMAP 'のような機能がありますが、ダイレクトメモリマッピングの上に構築されているため、ユーザスペースアプリケーションはネットワークソケットでより効率的に動作しますカーネル空間とユーザ空間の間で高価なデータをコピーすることなく直接パケットを取得/送信できます。これは 'mmap()'テクニックの明るい例であり、私が前のコメントで指摘したように、キャラクターデバイスが同じアプローチを展開するかもしれないようです。 –

+0

システムで許可されている場合は、DMAを使用できるはずです。 – DiegoSunDevil

答えて

0

get_user_pages() APIを使用して物理メモリからスワップアウトされたユーザーページを固定することができ、カーネルは対応する仮想アドレスの物理ページにアクセスしてこのメ​​モリ領域にアクセスできます。

3

まず、質問した質問に答えてみましょう。はい、あなたは、カーネルからユーザスペースによって割り当てられたメモリにアクセスできます。どのようにすればいいのかは分かりませんが、カーネルコードが呼び出しスレッドのコンテキストで実行されている場合、あなたに与えられたユーザースペースポインタを単純に使用することは可能かもしれません。

しかし、しないでください。

ユーザスペースポインタが不良であるか、メモリが短すぎるか、またはその他の問題が存在する場合、ユーザスペースプロセスはセグメンテーションフォールトでクラッシュする必要があるかもしれないからです。悲しいことに、あなたはユーザースペースコードを実行していない、あなたはカーネルスペースを実行しています。カーネルはセグメンテーションフォルトに相当し、カーネルパニックです。あなたのユーザーにそれを与えないでください。

よりよい方法は、ユーザー空間でデータを一度書き込んだ後、文字デバイスで単純に使用できる仕組みを使用することです。ユーザースペースがあると、そのページはコメントに記載されました。ファイルディスクリプタの仕組みの標準である方法は、デバイスのfileops構造体にsplice_readを実装することです。

spliceは使いやすいインターフェイスではありませんが、ソースがスプライス対応の場合でも、ユーザーはユーザー空間を通過することなくソースからドライバに直接データを渡すことができます。

コピーを保存する場合は、それらの解決方法のいずれかをお勧めします。繰り返しますが、ではなく、は、あなたが何をしているのか分からない限り、ユーザーが指定したポインタに直接アクセスします。

関連する問題