Научная статья на тему 'ДРАЙВЕРЫ LINUX: РАЗРАБОТКА TTY ДРАЙВЕРА ДЛЯ УСТРОЙСТВА PCI'

ДРАЙВЕРЫ LINUX: РАЗРАБОТКА TTY ДРАЙВЕРА ДЛЯ УСТРОЙСТВА PCI Текст научной статьи по специальности «Электротехника, электронная техника, информационные технологии»

CC BY
71
14
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ОПЕРАЦИОННАЯ СИСТЕМА LINUX / УСТРОЙСТВА PCI / ПОСЛЕДОВАТЕЛЬНЫЙ ПОРТ

Аннотация научной статьи по электротехнике, электронной технике, информационным технологиям, автор научной работы — Кувшинов Н.Е., Галяутдинов А.А.

В данной статье рассмотрены общие принципы и методы разработки TTY драйверов Linux для PCI устройств, выполняющих функцию последовательного порта.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

LINUX DRIVERS: DEVELOPMENT OF TTY DRIVER FOR PCI DEVICE

This article discusses general principles and methods of developing TTY Linux drivers for PCI devices that perform the function of a serial port.

Текст научной работы на тему «ДРАЙВЕРЫ LINUX: РАЗРАБОТКА TTY ДРАЙВЕРА ДЛЯ УСТРОЙСТВА PCI»

УДК 004.454

Кувшинов Н.Е.

инженер научно-исслед. лаборатории «ФХПЭ» Казанский государственный энергетический университет

Галяутдинов А.А. студент ИКТЗИ

Казанский национальный исследовательский технический

университет имени А.Н. Туполева - КАИ

Россия, г. Казань ДРАЙВЕРЫ LINUX: РАЗРАБОТКА TTY ДРАЙВЕРА ДЛЯ

УСТРОЙСТВА PCI

Аннотация: в данной статье рассмотрены общие принципы и методы разработки TTY драйверов Linux для PCIустройств, выполняющих функцию последовательного порта.

Ключевые слова: операционная система Linux, драйверы устройств, устройства PCI, устройства TTY, последовательный порт

Kuvshinov N.E., engineer laboratory "FHPE" Kazan State Power Engineering University

Russia, Kazan

LINUX DRIVERS: DEVELOPMENT OF TTY DRIVER FOR PCI

DEVICE

Annotation: this article discusses general principles and methods of developing TTY Linux drivers for PCI devices that perform the function of a serial port.

Keywords: Linux operating system, device driver, PCI device, TTY device, serial port.

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

Последовательный порт был популярен в прошлом, когда он использовался для подключения модемов, клавиатур и других периферийных устройств. С развитием технологий в персональных компьютерах последовательный порт практически полностью был заменён более быстрым и компактным интерфейсом USB. Но для специализированных устройств его использование остаётся актуальным ввиду возможности передачи на расстояния до нескольких десятков метров для стандарта RS-232 или до одного километра для RS-485. Ключевым устройством для работы с последовательным портом является универсальный асинхронный приёмопередатчик (УАПП, англ. Universal Asynchronous Receiver-Transmitter, UART). UART выполняет функцию преобразования данных в последовательный вид.

В системе Linux для передачи информации через

последовательный порт была разработана концепция системы, состоящей из драйвера UART порта, протокола передачи и драйвера TTY. На ядро TTY возложена обязанность следить за управлением потоком данных и за их формат. Это позволяет TTY драйверам заниматься только управлением оборудованием, а не организовывать взаимодействие с пространством пользователя. Также они позволяют производить настройку скорости передачи, режима проверки чётности и других параметров UART как с использованием интерфейса termios, так и непосредственно в консоли, используя утилиту stty.

В нашем случае мы рассматриваем подключение UART как PCI устройства. Стандарт PCI представляет собой как аппаратное подключение, так и программное обеспечение взаимодействия компонент. Для разработчиков модулей ядра Linux важной особенностью является автоматическая настройка PCI устройств во время загрузки системы. Таким образом драйверу необходимо только завершить инициализацию.

Каждому TTY драйверу необходимо создать struct tty_driver, которая описывает его и используется для регистрации и отмены регистрации в ядре TTY. Эта структура описана в файле <linux/tty_driver.h>. Поле magic всегда должно быть установлено в TTY_DRIVER_MAGIC, это необходимо чтобы ядро TTY знало, что действительно работает с TTY драйвером. Поле driver_name будет отображать драйвер в файле /proc/tty/drivers. Поле name определяет имена устройств в каталоге /dev. name_base необходимо только если младшие номера устройств должны начинаться не с нуля, практически для всех драйверов это поле должно быть установлено в ноль. Поля major, minor_start и num определяют старший номер для устройств, первый младший номер и максимальное количество устройств, которые могут быть зарегистрированы. type и subtype описывают тип TTY драйвера для ядра. Для работы с последовательными портами эти поля должны быть установлены в значения TTY_DRIVER_TYPE_SERIAL и SERIAL_TYPE_NORMAL соответственно. Поле init_termios используется для управления скоростью, и другими настройками передачи. Все указанные поля должны быть заполнены во время регистрации драйвера в ядре системы. struct tty_operations определяет список функций, поддерживаемых драйвером. В нашем случае необходимо определить только функции open, close и write.

static const struct tty_operations device _ops = { .open = device _open, .close = device _close, .write = device _write,

Листинг 1 - пример описания struct tty_operations

Для работы с PCI устройством необходимо указать ядру Linux с каким

именно устройством должен работать драйвер, для этого необходимо определить struct pci_device_id, в которой указываются идентификаторы производителя и устройства, описанные в документации к плате. Макрос MODULE_DEVICE_TABLE необходим для указания системе, с какими устройствами работает модуль.

static const struct pci_device_id device_ids[] = {

{ PCI_DEVICE(VENDOR_ID, DEVICE_ID) }, { /* empty */ },

};

MODULE_DEVICE_TABLE(pci, device_ids);

Листинг 2 - пример описания struct pci_device_id Основной структурой для драйвера PCI является struct pci_driver.

Для корректной работы необходимо определить поле name, которое будет отображено в /sys/bus/pci/drivers/. Поле id_table является указателем на struct pci_device_id. Поле probe - это указатель на зондирующую функцию, в ней производится настройка обнаруженного устройства. remove - указатель на функцию удаления PCI устройства из системы. Эти структуры описаны в файле <linux/pci.h>.

static struct pci_driver pci_driver = {

.name = "device_name", .id_table = device_ids, .probe = device_probe,

.remove = device_remove, };

Листинг 3 - пример описания struct pci_driver

В функции инициализации модуля необходимо зарегистрировать как TTY драйвер, так и драйвер PCI. Функция tty_alloc_driver должна быть вызвана для создания struct tty_driver с количеством поддерживаемых этим драйвером TTY устройств и значением флага драйвера, в качестве параметров. После этого следует заполнить поля этой структуры в соответствии с их описанием. Для регистрации TTY драйвера необходимо вызвать функцию tty_register_driver и pci_register_driver для PCI драйвера. В случае неудачи следует не забывать возвращать в систему занятые ресурсы, в зависимости от места возникновения ошибок используются функции tty_unregister_driver, put_tty_driver и pci_unregister_driver.

static int_init device_init(void)

{

int retval;

/* инициализация struct tty_driver */

tty_driver = tty_alloc_driver(TTY_MINORS, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); if (!tty_driver) { /* обработка ошибки */ }

{ /* заполнение полей struct tty_driver */ } tty_set_operations(tty_driver, &tpm_ops);

/* регистрация TTY драйвера */ retval = tty_register_driver(tty_driver); if (retval)

{ /* обработка ошибки */ } /* регистрация PCI драйвера */ retval = pci_register_driver(&pci_driver); if (retval)

{ /* обработка ошибки */ } return retval; }

Листинг 4 - пример описания функции инициализации В функции очистки необходимо освободить все ресурсы, занятые в функции инициализации.

При обнаружении новых PCI устройств, управление которыми должно быть передано их драйверу, вызывается зондирующая функция probe. В этой функции должны быть выполнены такие действия, как разрешение устройства - pci_enable_device и получение доступа к регистрам устройства. Для работы буфера чтения необходимо произвести инициализацию его структуры вызовом tty_port_init, прикреплённой к каждому устройству, которое будет зарегистрировано, произвести инициализацию оборудования и зарегистрировать TTY устройство - tty_port_register_device.

static int device_probe(struct pci_dev *pdev, const struct pci_device_id *dev_ids) {

DEVICE_STUCT *dev_st; /* структура, описывающая конкретное устройство */

struct device *tty_dev; int err;

/* разрешение устройства */ err = pci_enable_device(pdev); if (err)

{ /* обработка ошибки */ }

/* получение доступа к регистрам устройства */ dev_st ->baseAdr = ioremap(start, len); pci_set_drvdata(pdev, dev_st); /* заполнение dev_st */

/* инициализация структуры порта и регистрация устройства */ tty_port_init(&dev_st ->port);

tty_dev = tty_port_register_device(&dev_st ->port, tty_driver, devNo, &pdev->dev); if (IS_ERR(tty_dev)) { /* обработка ошибки */ }

devNo++; /* количество обнаруженных устройств */

return 0;

}

Листинг 5 - пример описания зондирующей функции probe

В функции удаления устройств remove необходимо, также, освободить все занятые ресурсы: tty_unregister_device - удалить TTY устройства, уничтожить порт вызовом tty_port_destroy, освободить ресурсы ввода-вывода и отключить устройство вызовом функции pci_disable_device.

В функции open должен быть обеспечен учёт количества открытий файла TTY устройства и установка требуемой конфигурации устройства.

Запрос линии прерывания request_irq должен производиться только при первом открытии. Аргументы функции не позволяют сразу обратиться к структуре устройства и идентифицировать открытое устройства можно, используя его младший номер, который хранится в поле index из struct tty_struct. Для быстрого доступа к структуре устройства можно сохранить указатель на неё в поле driver_data структуры struct tty_struct.

При последнем закрытии устройства должна быть выполнена функция free_irq для освобождения линии прерывания.

Функция write вызывается ядром TTY, когда готовы данные для отправки на TTY устройство, функция должна вернуть количество успешно переданных байт данных или отрицательный код ошибки. В этой функции данные должны быть записаны в регистры устройства для передачи, причём если нет возможности передать сразу всё сообщение, то лучше сразу вернуть количество реально переданных байт данных, а не погружать драйвер в сон.

Для чтения данных из устройства драйвер TTY не предполагает

отдельной функции, он должен только обеспечивать передачу данных в ядро TTY, где происходит буферизация данных. Таким образом драйверу нет необходимости организовывать логику буферизации. Передача данных в ядро TTY может происходить в контексте прерывания. Для отправки данных ядру необходимо вызвать функцию tty_msert_flip_char, аргументами её являются указатель на struct tty_port и значение флага. Если был получен обычный символ, то флаг должен иметь значение TTY_NORMAL, а если произошла ошибка при передаче, оно должно быть установлено в TTY_BREAK, TTY_FRAME, TTY_PARITY или TTY_OVERRUN. Для проталкивания информации пользователю после считывания данных необходимо вызывать функцию tty_flip_buffer_push.

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

Данная статья предназначена для людей уже имеющих представление о разработке драйверов для Linux, но возможно она будет полезна и тем, кто только начинает изучать данную область компьютерных технологий.

Использованные источники:

1. Корбет Д. Драйверы Устройств Linux, Третья Редакция [Текст]/ Д. Корбет, А. Рубини, Г. Кроах-Хартман. - Sebastopol: O'Reilly, 2005 .-636c.

2. The Linux Kernel API [Электронный ресурс] URL: https://www.kernel.org/doc/htmldocs/kernel-api/ (Дата обращения 13.04.2017)

Кувшинов Н.Е.

инженер научно-исслед. лаборатории «ФХПЭ» Казанский государственный энергетический университет

Галяутдинов А.А. студент ИКТЗИ

Казанский национальный исследовательский технический

университет имени А.Н. Туполева - КАИ

Россия, г. Казань ИСПОЛЬЗОВАНИЕ АППАРАТА НЕЙРОННЫХ СЕТЕЙ В СИСТЕМАХ СЕТЕВОЙ БЕЗОПАСНОСТИ Аннотация В данной работе рассмотрена возможность применения аппарата нейронных сетей для задач классификации мультимедийного трафика в телекоммуникационныхсетях. Для реализации одноклассового классификатора был выбран многослойный перцептрон. При исследовании современных атак на транспортном и/или межсетевом уровне сети, были выбраны следующие признаки: тип протокола, характеристики фрагментации, TTL, ToS, количество отправленных/полученных байт, IP-опции, корректность CRC, код и тип ICMP-сообщения, TCP-сессий продолжительность, количество флагов в сессии, менялся ли размер окна и другие.

i Надоели баннеры? Вы всегда можете отключить рекламу.