了解file_operations的loff_t * offp

我正在devise一个简单的读写字符缓冲区的设备驱动程序。 然而我的问题是关于file_operations结构read的两个函数。 我真的不明白什么loff_t *offp真的是。 我知道,对于读取和写入操作, *offp是文件偏移量,意味着文件的当前读/写位置,但是我甚至不确定写入或从设备文件读取的意味着什么。

从我所收集的内容来看,这就是我如何编写和从我的设备上读取的,是我创build了一个代表我的设备的结构,我将其称为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之外,文件位置或偏移量的概念是没有意义的,除非它指向内核中的缓冲内存的指针,用于某些任意的结构或types。 这是唯一的解释,我有文件偏移量…这是正确的? 这里的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如read / write被调用,并且我没有设置*offp ,最初设置的loff_t * offp是什么?

如果在最后一个file_operation offp = some_arbitrary_address(因为我这么说),那么当这个操作被再次调用时,offp将被设置为什么?

如果我有其他file_opens操作运行,它会设置为最后一个file_operation留下的内容,或者它会保留一个选项卡,使其使用哪个file_open操作并将* offpreplace为file_open具有的内容?

字符设备的概念对于我来说太抽象了,看起来设备本身并不像文件那样存储信息,而是保存信息的驱动程序。 我希望我已经解释了我的朦胧,我会清理任何我似乎模棱两可的东西。

“loff_t”是一个“长偏移”,即一个统一的off_toff64_t疯狂的多样性的寻找位置,使司机可以只使用loff_t而不用担心。

当你进入驱动程序时,指针本身指向用户提供的偏移量(假设用户代码正在执行驱动程序访问 – 技术上内核可以提供自己的访问权限,但用户案例是需要考虑的)通过lseeklseek64lseek64等,然后通过普通的读写操作。 考虑常规磁盘文件的情况:当你第一次open文件时,你(作为用户)让内核提供一个数据结构来跟踪你当前在文件中的位置,这样如果你readwrite一些字节,下一个readwrite从你离开的地方。

此外,如果你dup了文件描述符,或者通过forkexec来执行相同的命令,那么所有的继承进程都会共享这个seek-position。 因此,在shell提示下,命令:

 (prog1; prog2; prog3) > outputfile 

创建一个输出文件,然后将描述符prog2到三个程序中,以便在prog1输出之后, prog2写入的输出立即进入文件,而prog3输出跟随另外两个 – 所有三个单独的进程共享相同的底层内核数据结构与内部loff_t相同。

这同样适用于设备驱动程序文件。 当你的读写函数被调用时,你会收到用户提供的“当前偏移量”,你可以(也应该)根据需要更新它…假设有任何需要(例如,你想为用户提供常规文件的外观,包括在您读写时寻找偏移量的事实)。 如果器件具有寻道偏移的一些逻辑应用,那么可以在这里使用。

当然,还有更多的设备驱动程序,这就是为什么有这个东西(qv)的整本书章节。 🙂