0

I have read that device drivers in Linux can run either in user mode or in kernel mode.

I also know that IO devices are accessed in one of two ways: using port-mapped IO, or using memory-mapped IO.

In port-mapped IO, we access an IO device using the instructions IN and OUT, and in memory-mapped IO, the registers of an IO device gets mapped to the kernel space memory (so we can access them using regular CPU instructions that accesses memory, like mov).


Now I suppose you can have a device driver running in user mode if the device driver accesses the IO device not directly, but rather by talking to the device driver of the IO port that the IO device is plugged into (for example: by talking to the serial port device driver if the IO device is plugged into a serial port).

But if the IO device is using port-mapped IO, the IN and OUT instructions are privileged instructions, so you need to be in kernel mode to use them. and if the IO device is using memory-mapped IO, the IO device registers will be mapped to the kernel space memory, and you need to be in kernel mode to access the kernel space memory.

So I don't think that a device driver that accesses an IO device directly can run in user mode.

Am I correct, or am I missing something?

3

Q. IN and OUT instructions are privileged instructions, so you need to be in kernel mode to use them

iopl(). If the port numbers are low enough, you also have the option of using ioperm().

Apparently not supported on all architectures.

See Usage of inb, inl, inw to access kernel space from user space . This links to a how-to, and also an update to the example code.

Q. If the IO device is using memory-mapped IO, the IO device registers will be mapped to the kernel space memory, and you need to be in kernel mode to access the kernel space memory.

/dev/mem

This stuff was used by XFree86 / Xorg to drive graphics adaptors!

You forgot to mention interrupts. That's the hard part. Fortunately this is standarized for modern PCI devices, so they may be driven without needing a device-specific kernel driver. See Userspace I/O HOWTO: Generic PCI UIO driver

I'm not sure what the exact details and limitations for accessing PCI devices are.

DMA is not supported. You can write a minimal UIO driver to allow mapping some memory for DMA. See the UIO how-to. Then your userspace driver can carefully tell the device where to DMA to. If you get it wrong, the device might write to anywhere in your system RAM. Fun!

  • Didn't xorg use DRM ioctls to operate Graphic cards? – 炸鱼薯条德里克 Mar 9 at 4:12
  • 1
    @炸鱼薯条德里克: Basically all modern X drivers use DRM ioctl's, yes. But there was a phase when they didn't (e.g. in the nv driver), and legacy drivers still don't. Then there's also /dev/port, and the /sys/bus/pci/*/resource*/ files, which correspond to PCI card regions. All require apropriate permission. – dirkt Mar 9 at 5:51
  • Let's assume that a user mode program is now allowed to access an IO device, how is this functionality implemented? does Linux put a flag or something on the user mode program, and when the CPU is executing the user mode program, the CPU will see this flag and hence will allow the user mode program to use the IN and OUT instructions and access the kernel space memory (while remaining in user mode)? Or is it that the user mode program should call some Linux system calls in order to use the IN and OUT instructions and access the kernel space memory (the IO access is done in kernel mode)? – user340847 Mar 9 at 15:15
  • @user340847 it allows the user program to use IN / OUT instructions. If you look up IOPL, it is also the name of a pair of bits in x86 CPUs. – sourcejedi Mar 9 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.