Как 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, как вы указали.