Я хочу получить/dev/video0 из модуля ядра после инициализации камеры. Для этого я хочу создать узел/dev/video0 до запуска демона ueventd.Ядро Android: как создать/dev/video0 перед запуском daemon?
ответ
Глядя глубже обработку ядра в/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;
....
}