пятница, 10 июля 2015 г.

Как написать драйвер для com порта linux

Для вызова ioperm необходимо иметь права root; таким образом, вы должны запускать программу от пользователя root или установить на файл флаг setuid.

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

Этот способ конечно медленней, чем стандартный, но не требует ни оптимизации при компиляции, ни ioperm.

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

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

И, кроме того, сколько младших номеров нам нужно для девайса?

Если это вам мешает, поместите подпрограммы, работающие с портами ввода/вывода, в отдельный файл и компилируйте с оптимизацией только его.

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

Что если кто-то захочет подключить к компу 100 таких люстрочек?



Отсутствие ясных указаний должно подвигнуть нас на некоторые исследования.

Эти программы работают под Windows и предназначены для захвата данных, которые гуляют по USB-соединению.

Это наиболее общий подход для функций работы с файлами sysfs, образец можно найти в дереве исходников ядра для драйвера чипа I2C в drivers/i2c/chips.

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

Выполнение setuid для переключения на другого пользователя не отключает доступ к портам, данный ioperm, но это происходит при fork (наследованный процесс теряет доступ, когда как у порождающего процесса он остается).

Используйте уровень 3 (iopl(3) чтобы дать доступ вашей программе ко всем портам ввода/вывода (но будьте осторожны - доступ к неправильным портам может сделать некоторые нехорошие вещи с вашим компьютером).

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



Из-за ограничения в gcc (присутствующего, как минимум, в версии и ниже) и в egcs (всех версий вы должны компилировать любые исходные тексты, использующие эти процедуры, с включенной оптимизацией (gcc -O1 или выше или же определить пустое #define extern перед #include asm/io.

Последний аргумент - это двоичное значение, определяющее, дать ли доступ к портам (истина (1) или запретить его (ложь (0).

Выполнение setuid для переключения на другого пользователя не отключает доступ к портам, данный ioperm, но это происходит при fork (наследованный процесс теряет доступ, когда как у порождающего процесса он остается).

Полезным инструментом для этой работы будет свободная программка USB Snoopy, m/usbsnoopy; альтернативная версия программы SnoopyPro, t.

Итак, для готовности красного светодиода пользователь пишет 1 в красный файл, это событие вызывает функцию set_red в драйвере, что в свою очередь вызывает функцию change_color.

Процедуры доступа к портам ввода/выводы находятся в /usr/include/asm/io.



Редактор Don Marti притащил это забавное устройство под названием USB Visual Signal Indicator производства Delcom Engineering, оно показано на картинке 1.

Если это вам мешает, поместите подпрограммы, работающие с портами ввода/вывода, в отдельный файл и компилируйте с оптимизацией только его.

Макросы inb_p, outb_p, inw_p и outw_p работают аналогично вышеуказанным, но добавляют короткую (около микросекунды) задержку после доступа к порту; вы можете установить задержку около четырех микросекунд при помощи #define really_slow_IO перед #include asm/io.

Двоичное значение, результат: какие светодиоды горят 0x00 000, red, Green, Blue 0x01 001, red, Blue 0x02 010, green, Blue 0x03 011, blue 0x04 100.

Кроме того, если вы дадите доступ соответствующим пользователю/группе к файлу /dev/port, вашей программе не нужны права root - впрочем, это не очень хорошая вещь с точки зрения безопасности, поскольку это может нарушить работу системы путем получения прав root через доступ.

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

Процедуры представляют собой встроенные (inline) макроопределения, так что вам не нужны никакие библиотеки, и достаточно просто добавить #include asm/io.


Комментариев нет:

Отправить комментарий