Android内核:如何在ueventd守护进程启动之前创建/ dev / video0?

时间:2016-03-10 15:28:56

标签: android-kernel pandaboard

我希望在初始化摄像机后从内核模块访问/ dev / video0。 为此,我想在ueventd守护程序启动之前创建/ dev / video0节点。

1 个答案:

答案 0 :(得分:0)

更深入地了解/ dev / video0节点的内核处理 应用程序尝试打开此文件,它获取一个FILE * fp指针, linux内核虚拟文件系统检查这是否是常规文件或 设备文件,如果是设备文件,则检查它的主要编号 注册它的驱动程序并将次要编号保存在i_rdev字段中 struct inode * inode,它再次嵌入在struct file * fp和 传递给那个司机。

因此,对于应用程序打开的每个FILE * fp,都有struct file * fp in 注册驱动程序,即我们案例中的v4l2驱动程序。传递此文件指针 到内核​​ioctl API v4l2_ioctl。

现在内部v4l2驱动程序维护一个指向所有指针的数组 注册视频设备 如下所示: static struct video_device * video_device [VIDEO_NUM_DEVICES];

现在,如果我们看到主要的ioctl调用的实现。

static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
        struct video_device *vdev = video_devdata(filp);
    ...
}

该视频设备结构是从文件指针中提取的,文件指针是我们可以控制视频设备的关键,即我们的相机来自内核,因为它包含指向所有已注册的v4l2 ioctl的函数指针。所以我们的目标是从内核中访问视频设备结构。

现在再次查看内核在收到应用程序请求时如何访问视频设备。

struct video_device *video_devdata(struct file *file)

{
        return video_device[iminor(file->f_path.dentry->d_inode)];
}
EXPORT_SYMBOL(video_devdata);

static inline unsigned iminor(const struct inode *inode)
{
        return MINOR(inode->i_rdev);
}

如上所示,它使用i_rdev字段获取从struct file * fp传递给VFS的次要编号。

总结一下,如果我们想从内核中访问ioctl,我们需要填写 一个虚拟文件* fp指针,包含次要编号 file-> f_path.dentry-> d_inode.i_rdev字段,v4l2子系统将获得 video_device结构使用此字段并将能够进一步驱动 通过使用video_device-> ioctl_ops从video_device结构进行ioctl操作 字段如下所示。

struct video_device                                                             
{                                                                               
#if defined(CONFIG_MEDIA_CONTROLLER)                                            
        struct media_entity entity;                                             
#endif                                                                          
        /* device ops */                                                        
        const struct v4l2_file_operations *fops; 
    const struct v4l2_ioctl_ops *ioctl_ops;
    ...
}

要设置file-> f_path.dentry-> d_inode.i_rdev,我们需要在文件结构中添加对inode和dentry结构的引用,如下面的伪代码:

static int enumerate_camera()           
{                                                                                 

                        inode.i_rdev = cam_minor_number ;// Saved when camera device registered;        
                        dentry.d_inode = inode;        
                        file.f_path.dentry = dentry;   
                        file.f_dentry->d_inode = inode;
....                
  }