I want to access /dev/video0 from a kernel module after camera is initialized. For that I want to create /dev/video0 node before the ueventd daemon gets started.
1 Answers
Looking more deeply the kernel handling of /dev/video0 node whenever an application tries to open this file it gets a FILE *fp pointer , the linux kernel virtual file system checks whether this is a regular file or device file, and if it is a device file it checks it's major number to track the driver which registered it and saves the minor number in i_rdev field of struct inode *inode which is again embedded in struct file *fp and passed to that driver.
So for every FILE *fp opened by application there is struct file *fp in registered driver i.e v4l2 driver in our case. This file pointer is passed on to kernel ioctl API v4l2_ioctl.
Now internally v4l2 driver maintains an array of pointers to all the registered video devices as seen below : static struct video_device *video_device[VIDEO_NUM_DEVICES];
Now if we see the implementation of main ioctl call.
static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct video_device *vdev = video_devdata(filp);
...
}
This video device structure is extracted from file pointer which is the key by which we can control the video device i.e. our camera from within the kernel as it contains function pointers to all the registered v4l2 ioctls. So our target is to access the video device structure from within the kernel.
Now again looking at how kernel accesses the video device when it gets a request from application.
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);
}
As seen above it uses i_rdev field for getting the minor number passed from struct file *fp through VFS.
To summarise if we want to access ioctl from within the kernel we need to fill a dummy file *fp pointer containing minor number in file->f_path.dentry->d_inode.i_rdev field, v4l2 subsystem will get video_device structure using this field and will be able to drive further the ioctl operations from video_device structure by using video_device->ioctl_ops field as seen below.
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;
...
}
To set file->f_path.dentry->d_inode.i_rdev we need to add references to inode and dentry structure inside file structure as per below pseudocode:
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;
....
}

- 131
- 1
- 8