6

関数を使用して、ユーザー空間からカーネル空間に値をコピーしようとしています:

static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t  *off) 
{

    unsigned long copy=0;
    int desp=0; 

    copy = copy_from_user(&desp, &len, 4);  

    printk(KERN_ALERT "copy: %lx\n", copy);      
    printk(KERN_ALERT "desp: %d\n", desp);
}

ここで、「len」はユーザー空間に存在する変数で、カーネル空間の「desp」にコピーしたい

ユーザー空間から作成する関数呼び出しは次のとおりです (書き込みは file_operations 構造体によると device_write です):

 write (fd,buffer,8, &off);

「desp」に保存する必要がある値を印刷すると、常に0になります(8になるはずです)。私のコードの問題は何ですか? いくつかの例を見てきましたが、多くのバリエーションを実装しましたが、どれも機能しません。

4

2 に答える 2

7

マニュアルのwrite関数プロトタイプは次のとおりです。

ssize_t write(int fd, const void *buf, size_t count);

つまり、データが存在writeするファイル記述子と、書き込みたいバイトの3 つの値を に渡すだけで済みます。fdbuffercount

これはユーザー空間に関するものです。それでは、カーネル空間の書き込み関数、つまりdevice_write.

この関数への引数bufは、ユーザー空間から書き込みたいデータを含むものでありcount、カーネルによって書き込まれるために送信されるデータの長さです。したがってbuf、 ではなくポインタからデータをコピーすることになっていlenます。

したがって、正しい方法は次のようになります。

char *desp;  //allocate memory for this in kernel using malloc
copy_from_user (desp, buff, len);

これで十分です。

于 2013-07-06T09:07:43.863 に答える
4

lenユーザー空間には存在しません。値で渡されるためlen、カーネル空間で通常の変数としてアクセスできます。 desp = (int)lenは、あなたが必要とすることすべてです。ただし、size_t は int と同じではなく、64 ビット プラットフォームでは size_t は 8 バイトであることに注意してください。

copy_from_user()書き込もうとしているバッファ用です(bufferユーザー空間コードとbuffカーネル空間引数リストで呼び出されます)。渡されるのは、ユーザー空間にのみ存在するメモリアドレスへのポインターであるため、copy_from_user()そのバッファーをカーネル空間バッファーにコピーします。

于 2013-07-05T14:08:49.353 に答える