Подтвердить что ты не робот

Пользовательское пространство и драйвер пространства ядра

Я хочу написать драйвер PWM. Я знаю, что есть два способа управления аппаратным драйвером:

  • Пользовательский пробел.
  • Драйвер пространства ядра

Если вообще (не рассматривайте случай драйвера PWM), мы должны принять решение о том, следует ли искать пространство пользователя или драйвер пространства ядра. Тогда какие факторы мы должны учитывать помимо этих?

  • Драйвер пользовательского пространства может напрямую помещать файлы mmap()/dev/mem в их виртуальное адресное пространство и не требует переключения контекста.
  • В драйвере userpace не могут быть реализованы обработчики прерываний (они должны опросить прерывание).
  • Драйвер пользовательского пространства не может выполнять DMA (поскольку память с поддержкой DMA может быть выделена из пространства ядра).
4b9b3361

Ответ 1

От тех трех факторов, которые вы указали только в первом, действительно правильно. Что касается остального - не совсем. Кодер пространства пользователя может выполнять операции DMA - никаких проблем с этим. Существует много компаний-производителей оборудования, которые используют эту технику в своих продуктах. Также возможно иметь приложение, управляемое прерываниями, даже когда все операции ввода-вывода выполняются с полным обходом ядра. Конечно, не так просто сделать mmap() на /dev/mem.

У вас должна быть минимальная часть вашего драйвера в ядре - это необходимо для обеспечения вашего пользовательского пространства с минимальным минимумом, который требуется от ядра (потому что, если вы думаете об этом - /dev/mem, также резервное копирование драйвером персонального устройства).

Для DMA это на самом деле слишком прост - все, что вам нужно сделать, это обработать запрос mmap и сопоставить буфер DMA в пространстве пользователя. Для прерываний - это немного сложнее, прерывание должно обрабатываться ядром, независимо от того, что ядро ​​может не выполнять никакой работы и просто просыпать процесс, который вызывает, скажем, epoll_wait(). Другой подход заключается в том, чтобы доставить сигнал к процессу, как это сделано DOSEMU, но это очень медленно и не рекомендуется.

Что касается вашего фактического вопроса, одним из факторов, который вы должны принять во внимание, является совместное использование ресурсов. Пока вам не нужно делиться устройством с несколькими приложениями, и нет ничего, что вы не можете сделать в пользовательском пространстве - идите в пространство пользователя. Вероятно, вы сэкономите массу времени в течение цикла разработки, поскольку код пользовательского пространства очень прост. Когда, однако, двум или более приложениям необходимо разделить устройство (или его ресурсы), то есть вероятность, что вы потратите огромное количество времени, чтобы это стало возможным - просто представьте себе одновременное одновременное воспроизведение нескольких процессов, связанных с краской, сбоем, сопоставлением (той же?) Памяти и т.д. И в конце концов, IPC обычно выполняется через ядро, поэтому, если приложение должно начать "разговаривать" друг с другом, производительность может сильно ухудшиться. Тем не менее, это все еще выполняется в реальных приложениях для определенных приложений с критическими характеристиками, но я не хочу вдаваться в эти детали.

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

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

Ответ 2

Еще одно соображение: гораздо проще отлаживать драйверы пользовательского пространства. Вы можете использовать gdb, valgrind и т.д. Черт, вам даже не нужно писать свой драйвер в C.

Есть третий вариант, помимо просто пространства пользователя или драйверов пространства ядра: некоторые из них. Вы можете использовать только ядро-космос в драйвере ядра и делать все остальное в пространстве пользователя. Возможно, вам даже не придется писать драйвер пространства ядра, если вы используете фреймворк Linux UIO (см. https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html).

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

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