From what I understand:

  • Generally speaking, a driver runs in kernel space and can be called from user space.
  • Only code in kernel space can call usb low level things / ioctl
  • libusb is a library, so it will compile and run in user space

So how does libusb achieve low level USB?


Libusb is a library to interact with USB devices in the same manner that curses is a library to interact with text terminals, ALSA (more precisely its libasound component) is a library to interact with audi devices, etc. The kernel handles the hardware interactions. It provides device files that applications can open to interact with the hardware, through read, write and ioctl system calls.

ioctl is a system call: it allows applications (user-level code) to issue requests that are processes by the kernel.

Libusb allows applications to register callback functions which are executed when the device has something to report. Here's a rough overview of the information flow under the hood:

  • The electrical signal on the bus triggers an event on the USB controller.
  • The USB controller raises an interrupt signal on the main processor.
  • The processor executes the interrupt handler in the operating system kernel.
  • The kernel notices that a process is currently in a blocking read, write or ioctl system call on the device file and causes that system call to return.
  • In the user land process, when the system call returns, library code is executed.
  • The library code executes the callback function registered by the application programmer.
  • so no need to write device drivers for usb devices ? (unless maybe for speed optimization) – Thomas Jan 16 '14 at 8:28
  • @Thomas You need to write a kernel driver if you want to plug into a framework that's transport-independent: keyboard, storage, ethernet, etc. Otherwise, I think you only need a driver if the latency of a userland program is too high. – Gilles Jan 16 '14 at 9:27
  • If a device isn't recognized by the computer (no driver for it), will libusb still be able to access it ? – Thomas Jan 16 '14 at 11:07
  • @Thomas I don't know whether libusb can cope with all aspects of the USB protocol, but in principle, yes. A userland program can communicate with any RS232 serial device, via /dev/ttyS*. USB is the same principle, only faster and more complex. – Gilles Jan 16 '14 at 12:16

Linux uses two rings ring 0 is called kernel-level, ring 3 is called user-level. The connection from user to kernel is done (as it was already said) via syscalls. Between them are the libraries, as seen from the userland. So the most low level access to the kernel is implemented in libraries, for reasons of stability, security, synchronization, save spacing, and so on. The kernel-driver provides different interfaces to the userland: (ioctl, sysfs, sockets, character and block devices and so on) User Space Interfaces. So if you want, you can implement your access to the kernel driver by yourself omitting the libraries, or much easier compile your binary with static linked libraries.

A good starting point is to read the libusb sources, they are well documented.


It uses syscalls(2) and device files prepared by the kernel ( /dev/bus/usb/* )

  • So everything works as if the kernel made a special driver for unknown devices that accepts reads and writes ? How are we notified of interrupts and so on ? – Thomas Jan 15 '14 at 10:34

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.