使用container_of宏时获取错误数据

问题描述 投票:0回答:1

目前我遇到了container_of 宏的问题。在我的 skull_open 方法中,我想检索 struct sdev,它是我在 init 方法中初始化的。但是当我尝试访问此结构中的成员(在 open 方法中)时,我会得到一些未定义的值。所以我想的是我可能不理解container_of宏或者可能还有另一个我现在看不到的问题。

static int __init init_function(void){
    int err;
    struct cdev* kernel_object;
    struct scull_dev* sdev;
    if(scull_major){
        dev = MKDEV(scull_major,scull_minor);
        err = register_chrdev_region(dev,NUMBER_DEVICES,DEVICE_NAME);
    }
    else{
        err = alloc_chrdev_region(&dev,0,NUMBER_DEVICES,DEVICE_NAME);   
    }
    if(err){
       printk(KERN_WARNING "chrdev region couldn't be allocated!\n");
       return err;  
    }
    kernel_object = cdev_alloc();
    if(kernel_object == NULL){
       printk(KERN_WARNING "error allocating kernel object\n");
       return -1;
    }
    sdev = (struct scull_dev*)kmalloc(sizeof(struct scull_dev),GFP_KERNEL);
    sdev->cdev = kernel_object;
    sdev->quantum = QUANTUM;
    sdev->qset = Q_SET;
    skull_setup_cdev(sdev);
    allocate_memory(sdev);
    printk("device got registered and inited . ready for connections ... \n");
    return 0;
}
static void skull_setup_cdev(struct scull_dev* c_dev){
    int err;
    cdev_init(c_dev->cdev,&scull_fops);
    c_dev->cdev->owner = THIS_MODULE;
    //c_dev->cdev->ops   = &scull_fops;
    err = cdev_add(c_dev->cdev,dev,NUMBER_DEVICES);
    if(err){
       printk(KERN_WARNING "couldn't add structure to associated major. \n");
    }
}
static int skull_open(struct inode* inode, struct file* filep){
    struct scull_dev* s_dev;
    printk(KERN_INFO "openend skull device file ... \n");
    s_dev = container_of(&inode->i_cdev,struct scull_dev,cdev);
    printk("%d,%d\n",s_dev->quantum,s_dev->qset);
    filep->private_data = s_dev;
    return 0;
}
c linux driver
1个回答
0
投票

Linux 内核的

container_of
宏采用指向结构体成员的指针、结构体类型的名称和成员的名称,并生成指向该结构体的指针。有了这样的理解,请考虑这种用法:

    s_dev = container_of(&inode->i_cdev,struct scull_dev,cdev);

inode->i_cdev
是变量
i_cdev
所指向的
struct inode
的成员
inode
,因此
&inode->i_cdev
是指向
struct inode
成员的指针,而不是指向
struct scull_dev
成员的指针。因此,使用
container_of()
是不正确的。

inode->i_cdev
是指向
struct cdev
的指针。如果它恰好指向
struct cdev
,而它是
struct scull_dev
的成员,那么您可以像这样使用
container_of()
来获取指向后者的指针:

    s_dev = container_of(inode->i_cdev, struct scull_dev, cdev);

特别注意,传递的是指针

inode->i_cdev
本身,而不是该inode成员的地址。

当然,如果所指向的

struct cdev
不是
struct scull_dev
的成员,那么仍然会给你一个毫无意义的结果。

© www.soinside.com 2019 - 2024. All rights reserved.