カーネルモジュール用のcharデバイスを実装し、その読み込み関数を実装しました。 read関数は、呼び出し元にデータを返すためにcopy_to_user
を呼び出します。私はもともとブロック機能(wait_event_interruptible
)でread関数を実装しましたが、問題を再現するには、非ブロック的な方法で読み込みを実装しても問題ありません。私のコードはMIPSプロセッサで実行されています。copy_to_userがcharデバイスの読み込み関数でエラーを返します
ユーザー空間プログラムは、charデバイスを開き、スタックに割り当てられたバッファを読み込みます。
私が見つけたことは時々copy_to_user
は何バイトもコピーできません。さらに、copy_to_user
をmemcpy
(私はこれが正しいことではないことを知っています)の呼び出しで置き換えても、直ちに宛先バッファを印刷すると、memcpy
が失敗したことがわかります任意のバイトをコピーします。
これをさらにデバッグする方法がわかりません。なぜメモリがコピーされていないのかを判断するにはどうすればいいですか?プロセスコンテキストが間違っている可能性はありますか?
EDITは:
ユーザモード(繰り返し実行されます):
char buf[BUF_LEN];
FILE *f = fopen(char_device_file, "rb");
fread(buf, 1, BUF_LEN, f);
fclose(f);
カーネルモード:ここでは、コードが現在どのように見えるかを概説し、いくつかの擬似コードだ
char_device =
create_char_device(char_device_name,
NULL,
read_func,
NULL,
NULL);
int read_func(char *output_buffer, int output_buffer_length, loff_t *offset)
{
int rc;
if (*offset == 0)
{
spin_lock_irqsave(&lock, flags);
while (get_available_bytes_to_read() == 0)
{
spin_unlock_irqrestore(&lock, flags);
if (wait_event_interruptible(self->wait_queue, get_available_bytes_to_read() != 0))
{
// Got a signal; retry the read
return -ERESTARTSYS;
}
spin_lock_irqsave(&lock, flags);
}
rc = copy_to_user(output_buffer, internal_buffer, bytes_to_copy);
spin_unlock_irqrestore(&lock, flags);
}
else rc = 0;
return rc;
}
コードに問題がありますが、表示されません。 – Tsyvarev
@Tsyvarevいくつかの擬似コードを追加しました。うまくいけば、コードによって何が行われているかを十分に示してくれるでしょう。残念ながら、私はそれを小さな、再現する例に絞り込むことはできませんでした(まだ)。 – YSK
@YSKあなたは 'int rc'を2回宣言しました。 'int rc = copy_to_user(output_buffer、internal_buffer、bytes_to_copy);行から' int'を削除してください。 – Gaurav