2016-03-10 4 views

ответ

0

Глядя глубже обработку ядра в/Dev/узел video0 всякий раз, когда приложение пытается открыть этот файл, он получает указатель FILE * Fp, Ядро Linux проверяет виртуальная файловая система, будет ли это обычный файл или устройство файл, и если это файл устройства, он проверяет, является ли его основным номером отслеживание драйвера, который его зарегистрировал, и сохраняет второстепенное число в поле i_rdev struct inode * inode, который снова встроен в файл структуры * fp и , переданный этому файлу Водитель.

Так что для каждого FILE * fp, открытого приложением, есть файл структуры * fp в Зарегистрированный драйвер i.e v4l2 в нашем случае. Этот указатель файла передается по в ядро ​​ioctl API v4l2_ioctl.

Теперь внутренне v4l2 драйвер поддерживает массив указателей на всех зарегистрированных видеоустройств , как показано ниже: статическая структура 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 IOCTLs. Поэтому наша цель - получить доступ к структуре видеоустройства изнутри ядра.

Теперь снова посмотрим, как ядро ​​обращается к видеоустройству, когда оно получает запрос от приложения.

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 поля для получения младшего номера передается из файла * структуры FP через VFS.

Подводя итог, если мы хотим получить доступ к IOCTL внутри ядра, мы должны заполнить фиктивный указатель файла * Ф.П., содержащий незначительное количество в файл-> f_path.dentry-> d_inode.i_rdev поле, подсистема v4l2 получит video_device, используя это поле, и сможет управлять дальнейшими операциями ioctl с помощью структуры video_device с помощью видео_девиса-> ioctl_ops , как показано ниже.

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; 
    ... 
} 

Чтобы установить файл-> f_path.dentry-> d_inode.i_rdev нам нужно добавить ссылки на индексный дескриптор файла и структуру 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; 
....     
    }