34

I am looking to write a PWM driver. I know that there are two ways we can control a hardware driver:

  1. User space driver.
  2. Kernel space driver

If in general (do not consider a PWM driver case) we have to make a decision whether to go for user space or kernel space driver. Then what factors we have to take into consideration apart from these?

  1. User space driver can directly mmap() /dev/mem memory to their virtual address space and need no context switching.
  2. Userspace driver cannot have interrupt handlers implemented (They have to poll for interrupt).
  3. Userspace driver cannot perform DMA (As DMA capable memory can be allocated from kernel space).
Ciro Santilli OurBigBook.com
393k121 gold badges1.3k silver badges1.1k bronze badges
asked Mar 8, 2013 at 4:33
3
  • 1
    Security: file permissions of the device node control which users can open/read/write to the device. File operations deny or allow concurrent operations. Commented Mar 8, 2013 at 6:47
  • 1
    The decision may depend heavily on what you are PWM'ing, and using what hardware. Commented Mar 12, 2013 at 16:55
  • Also be aware that your kernel code must be placed under GPL. Commented Feb 7, 2020 at 14:27

2 Answers 2

43

From those three factors that you have listed only the first one is actually correct. As for the rest — not really. It is possible for a user space code to perform DMA operations — no problem with that. There are many hardware appliance companies who employ this technique in their products. It is also possible to have an interrupt driven user-space application, even when all of the I/O is done with a full kernel-bypass. Of course, it is not as easy simply doing an mmap() on /dev/mem.

You would have to have a minimal portion of your driver in the kernel — that is needed in order to provide your user space with a bare minimum that it needs from the kernel (because if you think about it — /dev/mem is also backed up by a character device driver).

For DMA, it is actually too darn easy — all you have to do is to handle mmap request and map a DMA buffer into the user space. For interrupts — it is a little bit more tricky, the interrupt must be handled by the kernel no matter what, however, the kernel may not do any work and just wake up the process that calls, say, epoll_wait(). Another approach is to deliver a signal to the process as done by DOSEMU, but that is very slow and is not recommended.

As for your actual question, one factor that you should take into consideration is resource sharing. As long as you don't have to share a device across multiple applications and there is nothing that you cannot do in user space — go for the user space. You will probably save tons of time during the development cycle as writing user space code is extremely easy. When, however, two or more applications need to share the device (or its resources) then chances are that you will spend tremendous amount of time making it possible — just imagine multiple processes forking, crashing, mapping (the same?) memory concurrently etc. And after all, IPC is generally done through the kernel, so if application would need to start "talking" to each other, the performance might degrade greatly. This is still done in real-life for certain performance-critical applications, though, but I don't want to go into those details.

Another factor is the kernel infrastructure. Let's say you want to write a network device driver. That's not a problem to do it in user space. However, if you do that then you'd need to write a full network stack too as it won't be possible to user Linux's default one that lives in the kernel.

I'd say go for user space if it is possible and the amount of effort to make things work is less than writing a kernel driver, and keeping in mind that one day it might be necessary to move code into the kernel. In fact, this is a common practice to have the same code being compiled for both user space and kernel space depending on whether some macro is defined or not, because testing in user space is a lot more pleasant.

Ciro Santilli OurBigBook.com
393k121 gold badges1.3k silver badges1.1k bronze badges
answered Mar 10, 2013 at 7:43
Sign up to request clarification or add additional context in comments.

2 Comments

However epoll has a fast mechanism at last it is a poll structure not an interrupt handler. It may cause problems with time critical operations.
@obayhan Could you elaborate on the poll problems with time critical operations? I use this "trick" and I'd like to know more.
10

Another consideration: it is far easier to debug user-space drivers. You can use gdb, valgrind, etc. Heck, you don't even have to write your driver in C.

There's a third option beyond just user space or kernel space drivers: some of both. You can do just the kernel-space-only stuff in a kernel driver and do everything else in user space. You might not even have to write the kernel space driver if you use the Linux UIO driver framework (see https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html).

I've had luck writing a DMA-capable driver almost completely in user space. UIO provides the infrastructure so you can just read/select/epoll on a file to wait on an interrupt.

You should be cognizant of the security implications of programming the DMA descriptors from user space: unless you have some protection in the device itself or an IOMMU, the user space driver can cause the device to read from or write to any address in physical memory.

answered Jun 7, 2013 at 17:34

1 Comment

Also it appears that VFIO is the shiny new mechanism to replace UIO: github.com/torvalds/linux/blob/v4.15/Documentation/vfio.txt

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.