Я разрабатываю драйвер устройства, который просто читает и записывает в символьный буфер.Мой вопрос, однако, касается двух функций в структуре file_operations
read
и write
.Я не совсем понимаю, что на самом деле loff_t *offp
.Я знаю, что для операций чтения и записи *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
?
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_, такая как чтение / запись, и я не установил *offp
лично, чтоloff_t * offp изначально установлен в?
Если в последнем file_operation offp = some_arbitrary_address (потому что я так сказал), это то, что будет установлено offp, когда эта операция будет вызвана снова?
Что произойдет, если у меня будут запущены другие операции file_opens, будет ли он установлен на то, что оставила для него последняя операция file_operation, или будет хранить вкладку, какую операцию file_open он использовал, и заменит * offp на то, что было в file_openв?
Концепция устройства char слишком абстрактна для меня, когда кажется, что само устройство даже не хранит информацию, как файл, а скорее это драйвер, который сохраняет информацию.Надеюсь, я объяснил свою туманность и проясню все, что мне кажется неоднозначным.