0

カメラの初期化後にカーネル モジュールから /dev/video0 にアクセスしたい。そのために、ueventd デーモンが開始される前に /dev/video0 ノードを作成したいと考えています。

4

1 に答える 1

1

アプリケーションがこのファイルを開こうとするたびに /dev/video0 ノードのカーネル処理をより深く調べると、 FILE *fp ポインターが取得されます。Linux カーネル仮想ファイル システムは、これが通常のファイルかデバイス ファイルかをチェックし、デバイスファイルに登録されているドライバーを追跡するためにメジャー番号をチェックし、構造体 inode *inode の i_rdev フィールドにマイナー番号を保存します。これは再び構造体ファイル *fp に埋め込まれ、そのドライバーに渡されます。

したがって、アプリケーションによって開かれたすべての FILE *fp に対して、登録済みドライバー (この場合は v4l2 ドライバー) に構造体ファイル *fp があります。このファイル ポインタは、カーネル ioctl API v4l2_ioctl に渡されます。

現在、v4l2 ドライバーは、以下に示すように、登録されているすべてのビデオ デバイスへのポインターの配列を内部的に保持しています

ここで、メインの 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);
}

上記のように、VFS を介して構造体ファイル *fp から渡されたマイナー番号を取得するために i_rdev フィールドを使用します。

要約すると、カーネル内から ioctl にアクセスする場合は、file->f_path.dentry->d_inode.i_rdev フィールドにマイナー番号を含むダミー ファイル *fp ポインターを埋める必要があります。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;
....                
  }                                                                       
于 2016-04-22T09:14:06.187 に答える