Кто-нибудь может мне объяснить,
- Что есть
IOCTL
? - Для чего его используют?
- Как я могу это использовать?
- Почему я не могу определить новую функцию, которая работает так же, как
IOCTL
?
источник
Кто-нибудь может мне объяснить,
IOCTL
?IOCTL
?An ioctl
, что означает «управление вводом-выводом», является разновидностью системного вызова для конкретного устройства. В Linux всего несколько системных вызовов (300-400), которых недостаточно, чтобы выразить все уникальные функции, которые могут иметь устройства. Таким образом, драйвер может определить ioctl, который позволяет приложению пользовательского пространства отправлять ему заказы. Однако ioctls не очень гибкие и имеют тенденцию быть немного загроможденными (десятки «магических чисел», которые просто работают ... или нет), а также могут быть небезопасными, поскольку вы передаете буфер в ядро - плохая обработка может нарушить вещи легко.
Альтернативой является sysfs
интерфейс, в котором вы настраиваете файл /sys/
и читаете / записываете его для получения информации от драйвера и для него. Пример того, как это настроить:
static ssize_t mydrvr_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", DRIVER_RELEASE);
}
static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);
И во время установки драйвера:
device_create_file(dev, &dev_attr_version);
Тогда у вас будет файл для вашего устройства /sys/
, например, /sys/block/myblk/version
для блочного драйвера.
Другой способ более интенсивного использования - это netlink, который представляет собой метод IPC (межпроцессного взаимодействия) для связи с вашим драйвером через интерфейс сокета BSD. Это используется, например, драйверами WiFi. Затем вы общаетесь с ним из пользовательского пространства, используя библиотеки libnl
или libnl3
.
ioctl
Функция полезна для реализации драйвера устройства для установки конфигурации на устройстве. например, принтер, который имеет параметры конфигурации для проверки и установки семейства шрифтов, размера шрифта и т. д.,ioctl
может использоваться для получения текущего шрифта, а также для установки нового шрифта. Пользовательское приложение используетioctl
для отправки на принтер кода, сообщающего ему вернуть текущий шрифт или установить новый шрифт.fd
- дескриптор файла, возвращаемый функциейopen
;request
это код запроса. напримерGETFONT
, получит текущий шрифт с принтера,SETFONT
установит шрифт на принтере;void *
. В зависимости от второго аргумента третий может присутствовать или отсутствовать, например, если второй аргумент естьSETFONT
, третьим аргументом может быть имя шрифта, например"Arial"
;int request
это не просто макрос. Требуется пользовательское приложение для генерации кода запроса и модуль драйвера устройства, чтобы определить, с какой конфигурацией на устройстве нужно играть. Приложение отправляет код запроса, используя,ioctl
а затем использует код запроса в модуле драйвера устройства, чтобы определить, какое действие выполнить.Код запроса состоит из 4 основных частей.
Если код запроса предназначен
SETFONT
для установки шрифта на принтере, направление передачи данных будет от пользовательского приложения к модулю драйвера устройства (пользовательское приложение отправляет имя шрифта"Arial"
на принтер). Если код запроса - этоGETFONT
направление от принтера к пользовательскому приложению.Для генерации кода запроса Linux предоставляет несколько предопределенных макросов, подобных функциям.
1.
_IO(MAGIC, SEQ_NO)
оба 8 бит, от 0 до 255, например, допустим, мы хотим приостановить работу принтера. Это не требует передачи данных. Итак, мы сгенерируем код запроса, как показано нижеи теперь используйте
ioctl
какСоответствующий системный вызов в модуле драйвера получит код и приостановит работу принтера.
__IOW(MAGIC, SEQ_NO, TYPE)
MAGIC
иSEQ_NO
такие же, как указано выше, иTYPE
задает тип следующего аргумента, вспомните третий аргументioctl
isvoid *
. W__IOW
указывает, что поток данных идет от пользовательского приложения к модулю драйвера. В качестве примера предположим, что мы хотим установить для шрифта принтера значение"Arial"
.дальше,
Теперь
font
это указатель, что означает, что это адрес, лучше всего представленный какunsigned long
, следовательно, третья часть_IOW
упоминает тип как таковой. Кроме того, этот адрес шрифта передается соответствующему системному вызову, реализованному в модуле драйвера устройства,unsigned long
и нам нужно привести его к правильному типу перед его использованием. Пространство ядра может получить доступ к пространству пользователя, и, следовательно, это работает. другие два функционально-подобных макроса - это__IOR(MAGIC, SEQ_NO, TYPE)
и,__IORW(MAGIC, SEQ_NO, TYPE)
где поток данных будет из пространства ядра в пространство пользователя и в обоих направлениях соответственно.Пожалуйста, дайте мне знать, если это поможет!
источник