Как Linux знает, какую функцию ioctl вызывать?

здесь ioctl вызов в пользовательском пространстве:

int ioctl(int fd, int cmd, ...);

насколько я знаю, когда мы хотим выполнить операции ввода-вывода, мы определяем наш собственный ioctl функция с набором запросов (команд), назначьте наш ioctl до file_operations структура такая:

struct file_operations fops = {
 .read = device_read,
 .write = device_write,
 .ioctl = device_ioctl, // device_ioctl is our function
 .open = device_open,
 .release = device_release,
};

и device_ioctl функция определяется по-разному по сравнению с интерфейсом пользовательского пространства:

static long device_ioctl(struct file *f, unsigned int cmd, unsigned long arg)

я думаю, что на основе дескрипторов файлов, ядро может получить соответствующая файловая структура и вызовы устройства ioctl.

это просто предположение, потому что я не могу найти его определение общей функции, где ядро выбирает соответствующий ioctl функция на основе файлового дескриптора fd перешел в общий ioctl интерфейс? Есть только 3 ioctl определения, которые я могу найти, но, по-видимому, это только определения устройств, а не ядро:функции ioctl

4 ответов


посмотрите в исходном коде Linux, fs / ioctl.c (http://lxr.free-electrons.com/source/fs/ioctl.c)
Там вы увидите syscall для ioctl:

SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)

это по очереди вызывает do_vfs_ioctl (), который вызывает vfs_ioctl (), который затем вызывает функцию unlocked_ioctl, определенную для этой файловой системы в структуре file_operations.
это будет ваша функция device_ioctl, которую вы зарегистрировали.


device_ioctl - это указатель на функцию. Ядро просто принимает fd как индекс массива struct file_operations и называет .ioctl соответствующего элемента. Ядру никогда не нужно знать, что такое сама функция, на какое устройство оно ссылается.

это основа "все является файлом", который является мото Unix.


когда вы называете ioctl вы передаете дескриптор файла. Вы получили файловый дескриптор от открытия файла устройства, такого как /dev/tty0:

$ ls -l /dev/tty0
crw--w---- 1 root tty 4, 0 Mar  6 10:47 /dev/tty0
$

количество 4 вот основной номер устройства, который закодирован в модуль драйвера, который должно использовать ядро.


ядро будет знать, какой ioctl функция для вызова из-за дескриптор. Чтобы иметь возможность вызывать ioctl () из userspace, вам нужно будет открыть файл, чтобы получить fd, типично a/dev / [some_device], драйвер которого будет реализовывать структуру file_operations, как вы указали.