Драйверу устройства ядра Linux требуется доступ к общему объекту в пространстве пользователя

Я пытаюсь написать драйвер сетевого устройства для Linux. У моего устройства есть доступный API, который позволяет мне получить доступ ко всем нужным мне функциям через общий объект, который существует в пользовательском пространстве.

Я хочу написать сетевой драйвер, чтобы устройство отображалось как интерфейс CAN. Однако для взаимодействия с устройством мне нужно использовать определенный общий объект, который существует в пользовательском пространстве.

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

Есть ли способ написать драйвер сетевого устройства в пользовательском пространстве? Или как лучше всего разработать решение?

Tl;Dr

Необходимо написать драйвер устройства для устройства, с которым можно взаимодействовать только из пользовательского пространства через предоставленный общий объект, предоставляющий API. Мне нужно, чтобы устройство отображалось как сетевой интерфейс, чтобы использовать утилиты SocketCAN и другие приложения, взаимодействующие с интерфейсами CAN в Linux.

Каковы мои варианты здесь? Что я могу сделать?

Спасибо!


person Thomas    schedule 17.10.2015    source источник
comment
Прежде всего, большое спасибо за информацию и участие. Я боялся, что меня посадят в бутылку за такой вопрос. Насколько я понимаю, нет способа создать сетевое устройство CAN из пользовательского пространства. По сути, это то же самое, что и любой другой элемент net_device в ядре, но с некоторыми измененными флагами, чтобы он стал CAN-устройством. Что мне нужно сделать, так это создать net_device, аналогичный тому, который вы видели бы для карты Ethernet или адаптера USB-Ethernet, проблема в том, что вместо записи в аппаратные регистры через PCI или USB мои единственные средства связи с устройством через этот SO-файл   -  person Thomas    schedule 18.10.2015
comment
Переместил мои комментарии в ответ, добавив кое-что к тому, что я сказал.   -  person Sam Protsenko    schedule 19.10.2015


Ответы (1)


То есть вы говорите, что в ядре вообще нет драйвера для вашего сетевого устройства, и к нему можно получить доступ только через какую-то пользовательскую библиотеку? В этом случае общая библиотека, которую вы упомянули, должна связываться с вашим сетевым устройством с помощью отображения памяти вашего /dev/mem, чтобы иметь возможность читать/записывать аппаратные регистры. Или, возможно, с помощью некоторого UIO.

Таким образом, ваш драйвер также должен быть разработан в пользовательском пространстве... Тогда фактический вопрос, который вы должны задать, заключается в том, как использовать ядро ​​CAN API из пользовательского пространства? И возможно ли это вообще в первую очередь? Для ответов, я думаю, вам следует посмотреть Documentation/networking/can.txt. И если ответ «нет» (означает, что вы не можете открыть интерфейс CAN из пользовательского пространства), тогда вам следует разработать также какой-нибудь драйвер ядра, который будет взаимодействовать с вашей частью пользовательского пространства, открывая интерфейс CAN.

В идеальном мире вся архитектура драйвера выглядела бы так:

Идеальная архитектура драйвера

Но для взаимодействия с твое устройство. Поэтому я предлагаю вам использовать следующую архитектуру драйвера, которая изображена на изображении ниже:

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

Предлагаемая архитектура драйвера

Короче говоря, ваше приложение и драйвер создают прокладку между SocketCAN API и API общей библиотеки.

Итак, вам нужно разработать 2 компонента:

  1. Driver (on kernel side). It's in charge of:
    • talking to SocketCAN utilities
    • общение с вашим приложением в пользовательском пространстве
  2. Application (in user-space); it's probably should be a daemon, as it's gonna be running constantly. It's in charge of:
    • talking to shared library
    • разговор с вашим водителем

Остается последний вопрос: какой API ядра использовать для взаимодействия между вашим драйвером пространства ядра и приложением пользовательского пространства (помеченным как IPC на картинке). Это строго зависит от того, какие данные вы собираетесь отправлять между двумя, и сколько данных вы хотите отправить, и какой способ отправки наиболее подходит для вашей задачи. Это также может зависеть от API вашей общей библиотеки: вы, вероятно, не хотите тратить много процессорного времени на преобразование формата сообщений (поскольку у вас уже есть triple переключение контекста с этой архитектурой драйвера, что не очень хорошо для производительности). Так что, вероятно, это должно быть что-то пакетно-ориентированное, например Netlink.

Следующее чтение может быть полезно, чтобы выяснить, какой IPC использовать:

person Sam Protsenko    schedule 18.10.2015
comment
Это именно то, что я имел в виду, но вы изложили это так здорово. Я новичок в написании кода ядра, и я хотел убедиться, что мой подход был правильным, большое спасибо за этот ответ! - person Thomas; 19.10.2015