- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在设计一个只读取和写入字符缓冲区的设备驱动程序。然而,我的问题是关于 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_operation如读/写被调用并且我没有亲自设置*offp
时,loff_t *offp初始设置是什么?
如果在最后一个 file_operation offp = some_arbitrary_address(因为我是这样告诉它的),那么当这个操作被再次调用时,offp 会被设置成什么?
如果我有其他 file_opens 操作正在运行,会发生什么情况,它会设置为最后一个 file_operation 留下的内容,还是会保留它使用的 file_open 操作的选项卡并将 *offp 替换为 file_open 所处的位置?
字符设备的概念对我来说太抽象了,因为设备本身似乎不像文件那样存储信息,而是保存信息的驱动程序。我希望我已经解释了我的困惑,并且我会澄清任何我似乎模棱两可的事情。
最佳答案
“loff_t”是一个“长偏移量”,即统一了 off_t
、off64_t
等疯狂多样性的搜索位置,以便驱动程序可以只需使用 loff_t,不用担心。
指针本身,在您进入驱动程序时,指向用户提供的偏移量(假设它是用户代码执行驱动程序访问——从技术上讲,内核可以提供它自己的,但用户情况是想一想)通过lseek
或llseek
或lseek64
等,然后通过普通的读写操作。考虑常规磁盘文件的情况:当您第一次打开
文件时,您(作为用户)让内核提供一个数据结构来跟踪您在文件中的当前位置,因此,如果您读取
或写入
一些字节,下一个读取
或写入
将从您停止的地方开始.
此外,如果您 dup
文件描述符,或通过(例如)fork
和 exec
执行等效的运行序列命令,所有继承进程共享该搜索位置。因此,在 shell 提示符下,命令:
(prog1; prog2; prog3) > outputfile
创建一个输出文件,然后 dup
将描述符发送给三个程序,以便 prog2
写入的输出在 的输出之后立即进入文件prog1
,prog3
的输出跟在其他两个之后——所有这一切都是因为所有三个独立的进程共享相同的底层内核数据结构和相同的内部 loff_t
。
这同样适用于设备驱动程序文件。当你的读写函数被调用时,你会收到用户提供的“当前偏移量”,你可以(并且应该)根据需要更新它......假设有任何需要(例如,你想为用户提供常规文件的外观,包括在您读写时查找偏移量移动的事实)。如果设备对查找偏移有一些逻辑应用,您可以在此处使用它。
当然,设备驱动程序还有很多内容,这就是为什么有整本书的章节都在讨论这个东西 (q.v.)。 :-)
关于c - 了解 file_operations 的 loff_t *offp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9713112/
声明: static char status[128] = "off\0"; 并实现了一个read函数: static ssize_t read_proc(struct file *filep, ch
我正在设计一个只读取和写入字符缓冲区的设备驱动程序。然而,我的问题是关于 file_operations 结构 read 和 write 中的两个函数。我真的不明白 loff_t *offp 到底是什
在以下函数中,取自 LDD: ssize_t read(struct file *filp, char __user *buff, size_t count, loff_t *offp); ssize
我是一名优秀的程序员,十分优秀!