[HN Gopher] USB for Software Developers: An introduction to writ...
___________________________________________________________________
USB for Software Developers: An introduction to writing userspace
USB drivers
Author : WerWolv
Score : 219 points
Date : 2026-04-08 19:23 UTC (8 hours ago)
HTML web link (werwolv.net)
TEXT w3m dump (werwolv.net)
| Neywiny wrote:
| But this kinda expects that your USB driver is the application
| code too, no? This is less of a driver and more of a library +
| program. If I have, say, a USB to Ethernet device, how do I hook
| this into the ethernet adapter subsystem?
| WerWolv wrote:
| On Linux you could create a tun/tap device from your
| application and translate data sent over that to requests sent
| to the ethernet adapter.
|
| Of course, when you're doing these things in userspace you
| either need some way of communicating with the Kernel or for
| the other subsystems to be in userspace as well.
| Neywiny wrote:
| Not to be too facetious but a great place for communicating
| with the kernel where there are a ton of other driver
| subsystems is... the kernel.
|
| Possibly a good addition to the article would be parallel
| development of an lkm. I guess it wouldn't have that windows
| interop but I would also be interested to see how this driver
| would be implemented on Windows. If it's idk 10x as many
| lines in the kernel vs userspace, that's a great benefit to
| the userspace approach.
| dist-epoch wrote:
| In HFT user-space networking drivers have a long history -
| there is too much latency induced by switching from kernel
| to user space to handle networking.
|
| > OpenOnload: A user-space network stack that intercepts
| socket calls to bypass the kernel network stack,
| accelerating standard socket operations for faster
| networking.
|
| > Netmap: A framework providing a simple API for high-speed
| packet I/O in user space, bypassing much of the kernel
| overhead for efficient packet forwarding and filtering.
|
| https://dysnix.com/blog/high-frequency-trading-
| infrastructur...
| WerWolv wrote:
| Arguably all these other subsystems shouldn't be in the
| Kernel either but that's a different topic :)
|
| There are quite a few benefits to doing these things in
| userspace over the Kernel, not really necessarily just
| because of the code size:
|
| - The code is much easier to write and debug, you just
| write code like you always would.
|
| - Bugs don't have the possibility to taking down your
| entire system or introduce vulnerabilities
|
| - Especially on Windows, everyone can do this without
| requiring an impossible to get driver signing certificate
| pjc50 wrote:
| Driver signing is a killer issue on Windows; if you put
| your machine into dev/unsigned mode you get an ugly banner
| that can't be turned off.
|
| Much easier to design the device to avoid that. E.g. by
| abusing USB-HID. The desktop USB missile launcher toy is
| USB HID, for example.
| kam wrote:
| No need to pretend to be HID. Windows has WinUSB for
| userspace USB drivers that don't need special signing.
| pjc50 wrote:
| Things which are relatively standard tend to get good generic
| support: Ethernet devices will generally be USB/CDC/ECM or
| RNDIS, for example. That may Just Work (tm) if it has the right
| descriptors.
|
| The userland approach is much more useful for weird or custom
| devices. In particular, on Windows you can do one of these user
| space "drivers" without having to bother with driver signing,
| and if you use libusb it will be portable too.
|
| (I maintain a small USB DFU based tool for work)
| Neywiny wrote:
| DFU - great example. If you have a USB device that has a DFU
| class that needs a custom driver, can dfu-util and the like
| hook into these userspace drivers? Or do you also need to
| maintain the application part?
| WerWolv wrote:
| dfu-util actually also just uses libusb under the hood! Any
| class or device that doesn't have a driver baked into the
| OS can be implemented like this. And if you'd need the DFU
| functionality in a different application, you may be able
| to just simply link parts of the dfu-util tool into your
| application
| pjc50 wrote:
| Dfu-util is one of those "user space drivers", so if you
| have a nonstandard protocol you'd have to add it directly
| to dfu-util. There's no intermediate API.
|
| It's not easy to set up a fake or "remapped" USB device on
| most OS as far as I'm aware, if you were trying to write an
| adapter program that modified USB packets.
| tosti wrote:
| The C++ looks messed up. I have yet to come across a keyboard
| that can type an arrow.
| Something1234 wrote:
| Some developers like ligature based fonts. They combine 2
| characters into one glyph
| tosti wrote:
| Thank you and the others who were kind enough to explain
| this. I've avoided such fonts like the plague. Didn't know it
| did arrows like that.
| quietbritishjim wrote:
| It's just a programming font ligature. If you copy and paste it
| you'll see the actual characters e.g. auto
| main() -> int {
|
| (It's also modern C++ trailing return type.)
| bheadmaster wrote:
| It's just "->" - the ligature font just renders it as a unitary
| arrow
| yellowapple wrote:
| Any keyboard can type "-" if you set up a compose key :)
| analog31 wrote:
| >>> Say you're being handed a USB device and told to write a
| driver for it.
|
| Hand it back, with a request to prove that it can't be done with
| one of the devices that the OS's already recognize as virtual COM
| ports.
| kevmo314 wrote:
| If you are interested in doing this in golang I wrote a library
| to avoid needing cgo: https://github.com/kevmo314/go-usb
|
| I use this to access UVC devices correspondingly without cgo:
| https://github.com/kevmo314/go-uvc
| kam wrote:
| And for Rust, https://github.com/kevinmehall/nusb
| yellowapple wrote:
| Perfect timing. I'm expecting to get my hands on a MOTU MIDI
| Express XT from my local Guitar Center within the next couple
| days (I paid for it when it arrived there a couple weeks ago, but
| they have a mandatory waiting period on used equipment to make
| sure it ain't stolen), which unfortunately uses some weird
| proprietary protocol instead of class-compliant MIDI-over-USB --
| so any use over USB from my PCs (nearly all of which are running
| Linux, OpenBSD, Haiku, or something other than Windows or macOS)
| is a no-go. This is okay for my immediate use cases (I just need
| it to route between some synth modules and controllers, without
| necessarily needing the PC to do any processing in-between), but
| it'd be cool to get the PC side of things working, too.
|
| There's an existing out-of-tree Linux driver1 that looks
| promising, but AFAICT it only does the bare minimum of exposing
| the MIDI ports for use with e.g. JACK, and it's also unclear how
| stable it is and whether it really does support the XT (the
| README says the kernel panic got fixed, but there are open issues
| about it; the README says the XT's supported, but there are open
| issues about that, too). I'd like to be able to create new
| routing presets and stuff like what the proprietary companion app
| can do, and I'd also like to be able to use the thing without
| needing to shove extra drivers into my kernel, and I'd also like
| to be able to use the thing on my OpenBSD and Haiku boxen, so
| I've been perusing LibUSB docs since a userspace USB driver that
| then presents the relevant MIDI ports _and_ some tooling to
| reroute the MIDI ports as desired seems like something useful.
| This article happens to be exactly what I 've been looking for
| w.r.t. a starting point for such a userspace driver.
|
| ----
|
| 1: https://github.com/vampirefrog/motu
| grawlinson wrote:
| I packaged that driver on the AUR, since I've got the same
| device. I can't get the binary blob to work (admittedly, I
| haven't tried very hard) and it's not high on my list of
| priorities so I'm okay using it as a dumb MIDI tool.
| kabir_daki wrote:
| Really useful introduction! Working with low-level hardware APIs
| is challenging but rewarding. The abstraction layers in modern OS
| make it easier but understanding what's underneath is invaluable.
| varispeed wrote:
| Ages ago when I was trying to create a simple USB device, I found
| that there is very much zero information how to do it - e.g. how
| to correctly write descriptors and so on. The typical advice was:
| find similar device to what you want to make, copy its
| descriptors and adapt to your own device using trial and error.
|
| Sounds like USB is a wonderful standard. Am I wrong?
| brcmthrowaway wrote:
| Dumb question.. do USB devices support DMA? Is it done through
| the host? Or does the USB device always push/pull data to host
| memory?
| kam wrote:
| USB devices cannot directly address host memory like PCIe or
| FireWire, but the XHCI controller does DMA to/from host memory,
| and most USB device controllers have some kind of DMA between
| USB and the device's RAM.
| brcmthrowaway wrote:
| Does the adb tool use libusb or a kernel driver?
| 2bird3 wrote:
| Nice article, happen to have been working on a usbip system for
| my Macbook M3 using similar tech.
|
| Worth noting that, this approach is limitted on newer macOS
| systems: can't build libusb "userspace USB drivers" for devices
| that are supported by macOS. Without manually disabling some
| Security features, can't override drivers for system-recognized
| USB devices.
| matheusmoreira wrote:
| I wish I could have read this article years ago. Reverse
| engineering my laptop's features would have been so much easier.
| My keyboard LED program is still among my favorite projects.
___________________________________________________________________
(page generated 2026-04-09 04:00 UTC)