目前我遇到了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;
}
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
的成员,那么仍然会给你一个毫无意义的结果。