c – 了解file_operations的loff_t * offp

前端之家收集整理的这篇文章主要介绍了c – 了解file_operations的loff_t * offp前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在设计一个只读取和写入字符缓冲区的设备驱动程序.但是我的问题是关于file_operations结构中的两个函数的读写.我真的不明白什么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,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的内容

一个char设备的概念对我而言太抽象了,因为它似乎设备本身甚至不能像文件一样存储信息,而是其保存信息的驱动程序.我希望我解释了我的雾气,我会清除任何我看起来模糊的东西.

感谢任何帮助:)

解决方法

“loff_t”是一个“长偏移量”,即一个统一了off_t,off64_t等的疯狂多样性的搜索位置,这样司机就可以使用loff_t,而不用担心.

当您进入驱动程序时,指针本身指向用户提供的偏移量(假设用户代码执行驱动程序访问 – 从技术上讲,内核可以提供自己的权限,但用户案例是要考虑的)通过lseek或llseek或lseek64等,然后通过普通的读写操作.考虑常规磁盘文件的情况:当您首次打开文件时,您(作为用户)获取内核以提供跟踪当前文件位置的数据结构,以便在读取或写入时一些字节,下一个读取或写入从你离开的地方拾起.

此外,如果您歪斜文件描述符,或者通过(例如)fork和exec等效于运行一系列命令,则该查找位置由所有继承的进程共享.因此,在shell提示符下,命令:

(prog1; prog2; prog3) > outputfile

创建一个输出文件,然后将描述符复制到三个程序,以便prog2写入的输出在prog1输出后立即进入该文件,并且prog3的输出跟随其他两个,因为所有三个独立进程共享相同的底层内核数据结构与内部loff_t相同.

这同样适用于设备驱动程序文件.当您的读写功能调用时,您将收到用户提供的“当前偏移量”,并且可以(并且应该)根据需要进行更新…假设有任何需要(例如,您想要向用户提供常规文件的外观,包括在读取和写入时寻求偏移移动的事实).如果设备有一些逻辑应用的seek偏移量,那么可以在这里使用.

当然,还有更多的设备驱动程序,这就是为什么有这些东西(q.v.)的整个书籍章节.

猜你在找的C&C++相关文章