1

私は pci デバイスを持っていますが、必要なのは /dev/pcidevice から "cat" してそのメモリを読み取ることだけです。char デバイスの read 関数の最初の試みは次のようになりました。

ssize_t cdev_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos) {

    ssize_t retval = 0;
    struct mypci_dev *device = filp->private_data;

/* reading data from pci device */
    device->values.fst = ioread16(device->bar[0]+OFFSET_FST);
    device->values.snd = ioread16(device->bar[0]+OFFSET_SND);
    ...
    device->values.lst = ioread16(device->bar[0]+OFFSET_LST);

    retval = copy_to_user(buffer, &device->values.fst, count);
    return retval;
}

そして、それはうまくいきませんでした:/ copy_to_user 行を次のように変更しました

retval = copy_to_user(buffer, "dummy", strlen("dummy")+1);

しかし、 cat /dev/pcidevice はまだ何も返しませんでした。

次に、すべての ioread16 呼び出しを cdev_open() にシフトすると、必要なものが得られました。しかし、なぜこのようにしか機能しないのか、今私は興味があります。そして、どうすればそれを他の方法で機能させることができますか? ATM コピーを開始するタイマーなどを考えていますが、ioreads が終了するまで何らかの待機があれば十分でしょう。何か案は?

4

1 に答える 1

1

copy_to_user()関数は、コピーできなかったバイト数を返します。成功すると、 を返します0。ここで、0 バイトを読み取ったときにユーザー空間がどれほど驚くか想像してみてください。

本当の問題は、それが実際に内部でどのように機能するcdev_open()かです。その関数の I/O バーを読み取り、ユーザー空間に何も送信しないことを願っています。その場合は、rmb();呼び出しの前に読み取りの後に追加して、copy_to_user()すべての読み取りが終了していることを確認してください (rmb()読み取りメモリ バリアです)。

また、LDDの第 3章と第 5 章をまだチェックしていない場合は、チェックしてください。

それが役に立てば幸い。ハッピーハッキング!

于 2013-02-28T18:01:47.717 に答える