文字バッファーを読み書きするデバイスドライバを設計しています。しかし、私の質問は、file_operations
構造体read
とwrite
の2つの機能に関するものです。私は本当にloff_t *offp
が本当に何であるかを理解していません。私は、読み取りと書き込みの両方の操作について、*offp
がファイルの現在の読み取り/書き込み位置を意味するファイルオフセットであることを知っていますが、デバイスファイルとの間での書き込みまたは読み取りの意味についてはわかりません。file_operationsのloff_t * offpを理解する
私が集めたことから、これは私が自分のデバイスから書いたり読んだりしているところです。これはmy_char_struct
と呼ばれる私のデバイスを表す構造を作成することです。
struct my_char_structure{
struct cdev my_cdev;
struct semaphore sem;
char *data;
ssize_t data_size;
unsigned int access_key;
unsigned long size;
};
これが初期化され、私のドライバーのようなinsmod
あるときに指摘された静的な構造です。
static dev_t dev_num;
static struct my_char_structure Dev;
int start_mod(void){
//Because we are dealing with a fictitious device, I want
//the driver to create my two devices with arbitrarily
//assigned major numbers.
struct my_char_structure *my_dev = &Dev;
int err;
alloc_chrdev_region(&dev_num, FIRST_MINOR, COUNT, DEVICE_NAME);
sema_init(&(my_dev->sem),1);
cdev_init(&(my_dev->my_cdev), &fops);
my_dev->my_cdev.owner = THIS_MODULE;
my_dev->my_cdev.ops = &fops;// fops is my file operations struct
err = cdev_add(&my_dev->my_cdev, dev_num, COUNT);
if(err<0)
printk(KERN_ALERT "There was an error %d.",err);
printk(KERN_ALERT " insmod to major number %d",MAJOR(dev_num));
return 0;
}
module_init(start_mod);
私のデバイスが開いているとき、私はちょうど私のような
module_init(start_mod)
時に設定したその静的な構造を指すように開いたファイルのポインタを作る
...
int dev_open(struct inode *in_node, struct file *filp){
static struct my_char_structure *my_dev;
my_dev = container_of(in_node->i_cdev, struct my_char_structure, my_cdev);
printk(KERN_ALERT "The device number is %d",iminor(in_node));
if(!my_dev)
printk(KERN_ALERT "something didn't work. my_dev not initialized.");
filp->private_data = my_dev;
return 0;
}
何私読み書きメソッドは、私がオープンファイルで指摘した初期構造のDevを変更しています。どんなものでも私の構造からのcopy_to_user
は、ユーザーがデバイスに書いたものとみなされ、ユーザーが書いていると思っているものは何でもcopy_from_user
です。しかし、私の初期構造Devを変更する以外に、ファイルの位置やオフセットの考え方は、任意の構造やタイプのカーネル内でバッファされたメモリへのポインタを参照しない限り意味がありません。それは私がファイルのオフセットに対して持っている唯一の解釈です...これは正しいのですか?それはloff_t *offp
がここに言及しているのでしょうか?そのような読み取り/書き込みなど、いくつかのfile_operationが最初に設定offp *と呼ばれ、私がloff_tされているもの、個人的に*offp
を設定していなかった?(私の理解が正しけれ与えられた)
write(struct file *filp, const char __user *buff, size_t count, loff_t *offp)
read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
最後のfile_operationでoffp = some_arbitrary_address(私がそう言ったからです)が、この操作が再度呼び出されたときにoffpが設定されるのはどうでしょうか?
他のfile_opens操作が実行されている場合は、最後のfile_operationをそのまま残すか、file_open操作のタブを保持して* offpをfile_openのものに置き換えますか?
文字デバイスのコンセプトは、デバイス自体がファイルのように情報を格納するのではなく、情報を保存するドライバであると思われるときには抽象的すぎます。私は私の曇りを説明してくれることを願っています。
オフセットをoffset = = bytes_read/writeに変更すると、ユーザーポインタは変更されますが、自動的には行われませんか?私はこれが私のためにいくつかのものをクリアすると思う。私はlinuxのデバイスドライバの第3版の本を読んでいました。誰もが紹介していて、オフセットポインタがファイル位置と呼ばれる奇妙なカーネル抽象化(より良い言葉の欠如)を参照していたこの図がありました。助けてくれてありがとう、この種のものをクリアする:) –
はい。 (おそらくあなたは '* offp + = nbytes'を意味します。)変更している変数は実際にはカーネルスペースのものですが、*はユーザーのシークオフセットを表します*。 (あるいは、 'pread'や' pwrite'呼び出しに与えられたオフセット、あるいは何か他のものですが、たいていの場合、ユーザの 'lseek'オフセットです。)あなたが呼び出すように、"奇妙なカーネル抽象化 " '(prog1; prog2)> output'を動作させるものです。ちなみに、* BSDカーネルには、あなたのための "ユーザI/Oオフセット"を自動的に更新する 'uiomove'という関数があります。 Linuxはまったく逆の方向に進みました。 – torek