Как мне использовать ioctl () для манипулирования моим модулем ядра?

Если вы перечислите все свойства window.navigator, используя

console.log(navigator);

, вы увидите что-то вроде этого

# platform = Win32
# appCodeName = Mozilla
# appName = Netscape
# appVersion = 5.0 (Windows; en-US)
# language = en-US
# mimeTypes = [object MimeTypeArray]
# oscpu = Windows NT 5.1
# vendor = Firefox
# vendorSub = 1.0.7
# product = Gecko
# productSub = 20050915
# plugins = [object PluginArray]
# securityPolicy =
# userAgent = Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7
# cookieEnabled = true
# javaEnabled = function javaEnabled() { [native code] }
# taintEnabled = function taintEnabled() { [native code] }
# preference = function preference() { [native code] }

. Обратите внимание, что атрибут oscpu дает вам версии Windows. Кроме того, вы должны знать, что:

'Windows 3.11' => 'Win16',
'Windows 95' => '(Windows 95)|(Win95)|(Windows_95)',
'Windows 98' => '(Windows 98)|(Win98)',
'Windows 2000' => '(Windows NT 5.0)|(Windows 2000)',
'Windows XP' => '(Windows NT 5.1)|(Windows XP)',
'Windows Server 2003' => '(Windows NT 5.2)',
'Windows Vista' => '(Windows NT 6.0)',
'Windows 7' => '(Windows NT 6.1)',
'Windows 8' => '(Windows NT 6.2)|(WOW64)',
'Windows 10' => '(Windows 10.0)|(Windows NT 10.0)',
'Windows NT 4.0' => '(Windows NT 4.0)|(WinNT4.0)|(WinNT)|(Windows NT)',
'Windows ME' => 'Windows ME',
'Open BSD' => 'OpenBSD',
'Sun OS' => 'SunOS',
'Linux' => '(Linux)|(X11)',
'Mac OS' => '(Mac_PowerPC)|(Macintosh)',
'QNX' => 'QNX',
'BeOS' => 'BeOS',
'OS/2' => 'OS/2',
'Search Bot'=>'(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves/Teoma)|(ia_archiver)'
13
задан Ciro Santilli 新疆改造中心法轮功六四事件 30 November 2018 в 18:40
поделиться

2 ответа

echo "Hi All" | tr "[:upper:]" "[:lower:]"
-121--1757343-

Отсутствует указатель функции .open в структуре file _ operations для указания функции, вызываемой при попытке процесса открыть файл устройства. Необходимо также указать указатель функции .ioctl для функции ioctl.

Попробуйте прочитать Руководство по программированию модуля ядра Linux , в частности главы 4 (Символьные файлы устройств) и 7 (Разговор с файлами устройств).

Глава 4 описывает структуру file _ operations , которая содержит указатели на определенные модулем/драйвером функции, выполняющие различные операции, такие как open или ioctl .

Глава 7 содержит информацию о взаимодействии с модулем/диском через ioctls.

Драйверы устройств Linux, третье издание - еще один хороший ресурс.

-121--2664688-

Необходимый Вам пример кода можно найти в drivers/watchdog/softdog.c (из Linux 2,6,33 на момент написания), который иллюстрирует правильные операции с файлами, а также как разрешить пользователю заполнять структуру ioctl ().

На самом деле это отличный рабочий учебник для всех, кому нужно писать тривиальные драйверы устройств.

При ответе на мой собственный вопрос , который может быть вам полезен, я проанализировал ioctl-интерфейс софтдога.

Вот суть этого (хотя и далеко не исчерпывающая)...

В softdog _ ioctl () вы видите простую инициализацию watchdog_info структуры, которая рекламирует функциональность, версию и информацию об устройстве:

    static const struct watchdog_info ident = {
            .options =              WDIOF_SETTIMEOUT |
                                    WDIOF_KEEPALIVEPING |
                                    WDIOF_MAGICCLOSE,
            .firmware_version =     0,
            .identity =             "Software Watchdog",
    };

Мы рассмотрим простой случай, когда пользователь просто хочет получить эти возможности:

    switch (cmd) {
    case WDIOC_GETSUPPORT:
            return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;

... который, конечно, заполнит соответствующий watchdog_info пользовательского пространства инициализированными значениями выше. Если ошибка copy_to_user (), возвращается -EFAULT, что приводит к тому, что соответствующий вызов userspace ioctl () возвращает -1 со значимым устанавливать errno.

Обратите внимание, что магические запросы фактически определены в linux/watchdog.h, так что ядро и пользовательское пространство разделяют их:

#define WDIOC_GETSUPPORT        _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
#define WDIOC_GETSTATUS         _IOR(WATCHDOG_IOCTL_BASE, 1, int)
#define WDIOC_GETBOOTSTATUS     _IOR(WATCHDOG_IOCTL_BASE, 2, int)
#define WDIOC_GETTEMP           _IOR(WATCHDOG_IOCTL_BASE, 3, int)
#define WDIOC_SETOPTIONS        _IOR(WATCHDOG_IOCTL_BASE, 4, int)
#define WDIOC_KEEPALIVE         _IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
#define WDIOC_SETPRETIMEOUT     _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
#define WDIOC_GETPRETIMEOUT     _IOR(WATCHDOG_IOCTL_BASE, 9, int)
#define WDIOC_GETTIMELEFT       _IOR(WATCHDOG_IOCTL_BASE, 10, int)

WDIOC, очевидно, означает «Watchdog ioctl»

Вы можете легко сделать это шаг дальше, имея ваш драйвер сделать что-то и поместить результат этого в структуру и скопировать его в пользовательское пространство. Например, если структура watchdog_info также имела члена __ u32 result_code. Обратите внимание, что __ u32 является только версией ядра uint32 _ t .

С помощью ioctl () пользователь передает адрес объекта, будь то структура, целое число, в ядро, ожидающее, что ядро запишет свой ответ в идентичный объект и скопирует результаты на предоставленный адрес.

Второе, что вам нужно сделать, это убедиться, что ваше устройство знает, что делать, когда кто-то открывает, читает с него, пишет на него или использует крючок, как ioctl (), который вы можете легко увидеть, изучая программное обеспечение.

Интерес представляют:

static const struct file_operations softdog_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = softdog_write,
        .unlocked_ioctl = softdog_ioctl,
        .open           = softdog_open,
        .release        = softdog_release,
};

Где вы видите обработчик unlocked_ioctl... вы догадались, softdog_ioctl ().

Я думаю, что вы можете сопоставить уровень сложности, который действительно не существует при работе с ioctl (), это действительно так просто. По этой же причине большинство разработчиков ядра хмурятся над новыми интерфейсами ioctl, добавляемыми, если они не являются абсолютно необходимыми. Его слишком легко потерять трек типа, который ioctl () собирается заполнить против магии вы используете, чтобы сделать это, что является основной причиной, что copy_to_user () терпит неудачу, часто приводя к гниение ядра с полчищами процессов userspace застряли в дисковый сон.

Для таймера, я согласен, ioctl () является кратчайшим путем к здравомыслию.

20
ответ дан 1 December 2019 в 08:52
поделиться

В структуре file_operations отсутствует указатель на функцию .open для указания функции, которая будет вызываться при процесс пытается открыть файл устройства. Вам также нужно будет указать указатель на функцию .ioctl для вашей функции ioctl.

Попробуйте прочитать Руководство по программированию модуля ядра Linux , особенно главы 4 (Файлы символьных устройств) и 7 (Обращение к файлам устройств).

Глава 4 представляет структуру file_operations , которая содержит указатели на функции, определенные модулем / драйвером, которые выполняют различные операции, такие как open или ioctl ].

Глава 7 предоставляет информацию о связи с модулем / приводом через ioctls.

Драйверы устройств Linux, третье издание - еще один хороший ресурс.

8
ответ дан 1 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: