[HN Gopher] Writing a basic Linux device driver when you know no...
___________________________________________________________________
Writing a basic Linux device driver when you know nothing about
Linux drivers
Author : sbt567
Score : 412 points
Date : 2025-06-22 10:29 UTC (4 days ago)
(HTM) web link (crescentro.se)
(TXT) w3m dump (crescentro.se)
| ianlevesque wrote:
| It's a userspace USB HID driver in rust, which is honestly more
| interesting/applicable to me than a kernel driver, which is what
| I thought it meant from the title.
| ahartmetz wrote:
| > I also thought I'd message the vendor and ask them if they
| could share any specifications or docs regarding their protocol.
| To my surprise, Nanoleaf tech support responded to me within 4
| hours, with a full description of the protocol that's used both
| by the Desk Dock as well as their RGB strips.
|
| How cool is that? Too many vendors still think that they have
| valuable intellectual property in such relative trivialities. And
| that handing out the specs freely helps their competitors more
| than themselves.
| starkrights wrote:
| I had the same reaction. Nano leaf is extremely cool for that.
| baby_souffle wrote:
| This has to put them in the top 0.01% of companies that make
| consumer electronics.
|
| I can think of only a few companies that bother to publish
| any details... And most of them are focused on industrial
| customers where it isn't unreasonable to need certain
| protocol details for integration or even just compliance with
| certain regulatory systems.
|
| Maybe things are changing?
|
| I have noticed that some of the LED light controllers you see
| on AliExpress are leaning in to open firmware standards. 5
| years ago, you bought the controller and had to flash your
| own firmware. Now, there's an option at checkout to select an
| open source firmware. Some even have a USB port built in for
| flashing!
| pipe01 wrote:
| It really makes me wonder why it's not more common. They
| literally don't have to write any firmware, just use one of
| the thousands already available provided that the license
| allows for it
| Teknoman117 wrote:
| I almost had that experience with one of the popular PC liquid
| cooling hardware vendors around 10 years ago.
|
| I emailed them saying I'd be interested in developing drivers
| for their hardware for Linux as I was a happy customer and was
| immediately put in touch with one of the managers and their
| engineering team.
|
| Made quite a bit of progress before the whole thing was shut
| down because one of their component vendors threatened them
| saying it'd be a breach of their contract with them.
|
| Apparently that vendor sold a "datacenter" (non consumer)
| version of that hardware for which they charged a hefty license
| fee for the management software (which was Linux compatible).
|
| Jokes on them, someone reverse engineered the whole thing with
| a USB analyzer years later and published it XD. (not me)
| agentkilo wrote:
| Yeah that part of the article put a big smile on my face.
|
| I did the same thing back in college, when I was in a lab. We
| wanted to do some research on Wi-Fi signals, and I happened to
| own a bunch of Wi-Fi adaptors produced by SomeSmallTech Co.
| Ltd., which featured relatively new Atheros chips and didn't
| have Linux drivers at the time.
|
| So I sent an email to the company's public email address,
| asking for some datasheets, "for science". To my
| disappointment, presumably a PR person replied that they "don't
| have a company policy to collaborate with academic research".
| (But they did send a quick reply, kudos to that.)
|
| Funnily enough, years later I ended up working for said
| company. Naturally, when I first logged into the company
| network, I searched for the datasheets I asked for. There were
| "classified" watermarks all over the PDFs :)
| wiz21c wrote:
| > don't have a company policy to collaborate with academic
| research"
|
| Strangely they all have a tacit policy to build their
| products at least partly on the results of academic research.
| 2Gkashmiri wrote:
| I have a solar inveter from a company, aparticular German
| brand. I wanted to use home assistant with it so I needed rs232
| data.. tried the support and they asked me to sign an NDA.
|
| Okay, cool. I did with a fake name, address and everything and
| they sent a file..
|
| Turns out the file is available online.
|
| Facepalm pro Max.
|
| So my question is, what kind of "IP" is in a data sheet that
| needs protection ? And this isnt even some secret product but a
| generic solar product sold by millions.
|
| Rs-232 protocol ? Really ?
| wiz21c wrote:
| They have asked to the legal team who basically don't know
| shit about what us do and who will always take the most
| conservative approach possible. So you'll get either: no
| answer, a "NO" answer or an "NDA" answer.
| tialaramex wrote:
| Yup. The default from lawyers will be "No" because why
| help? The correct way to use lawyers, either in-house
| counsel or a paid lawyer if you have a specific project is
| to tell them what you _want_ to happen and then they figure
| out what the best legal course of action is to closest
| achieve that. Mundanely this might mean e.g "Fill out form
| X1234 and then send letters to this politician suggesting
| they support your X1234 application" but at the extreme it
| could mean closer to the situation in the UK where a ferry
| company illegally fired crews with zero notice, and their
| legal advice had clearly been "Worst case they put one of
| your executives in prison, probably not even that, but
| either way you replace union workers with people on slave
| wages and that means $$$".
| Mad_ad wrote:
| Was it Alpha-ESS? they make it so stupidly hard to get your
| information outside of their smartphone app.
| ainiriand wrote:
| Germans germaning!
| ahartmetz wrote:
| Even though there are much fewer lawyers in Germany and
| they are less involved in running companies (like in any
| country, compared to the US).
| sysmax wrote:
| It's not the IP, it's sadly how people react. Some folks will
| be appreciative of help, credit to them. Others will
| immediately get back how they tried it, it didn't work and now
| they need you to rewrite everything, or do their project for
| them, or redesign your product to match what they want it to
| be. And if you politely refuse, it quickly escalates to threats
| of trashing your business through every channel, and other
| things.
|
| So, the safest thing to do is not give details at all, or
| "leak" them like another reply in this thread mentions.
| amelius wrote:
| I wish more vendors would put "Linux support" on the package.
| Or maybe "Unofficially supported in Linux" or "Linux community
| support" if they don't want to get their fingers burned.
|
| Maybe this kind of thing should be enforced in the GPL (as many
| devices use Linux under the hood).
| ahartmetz wrote:
| IME, Linux support is often mentioned on the package these
| days. But you still need to look it up anyway because it's
| often a vendor source dump for a particular kernel version.
| Such drivers are often not that good. Notable exception: my
| Brother printer-scanner-copier has been working fine with its
| vendor-provided user space driver for ~10 years now. I think
| it has not been updated for most of that time. It contains 32
| bit binaries!
| BobbyTables2 wrote:
| Or worse, they just reply "Linux is not supported" ...
| jonnypotty wrote:
| Thanks for this. Good read and also kinda inspiring.
| dabedee wrote:
| I really enjoyed the way this post was written, i.e. it includes
| the code, how it was run, the false paths, etc. You almost get to
| live through the author's journey and how he figured out just
| enough to get something working.
| kblissett wrote:
| I enjoyed this post, but I'm eager to hear what the next step
| would be for a real "production" userspace driver. Are these
| typically just daemons that are configured to run at start up?
| And then some configuration GUI communicates with it over a
| socket or something?
| ItsHarper wrote:
| You could certainly do that, and it would make a ton of sense
| if there's both no standard software API for communicating with
| that type of device, _and_ it 's important that multiple pieces
| of software that communicate with the device are able to run at
| the same time (or you want to avoid repeating work when
| starting software multiple times). ADB (Android Debug Bridge)
| takes this approach.
|
| If there _is_ an applicable standard software API (either
| multiplatform like a filesystem, or a special one exposed by
| the OS kernel [1] ), the driver probably belongs in the Linux
| kernel (or in the form of a Windows driver on that platform).
| My understanding is that GPU APIs are an exception on Linux,
| and are implemented in userspace by a piece of software called
| MESA. You could also use the daemon approach in this case if
| you don 't want to bother with getting a driver added to the
| kernel.
|
| For a more niche device where exclusive access is acceptable
| and every piece of software would need to add special support
| for this specific type of device anyway, it's a lot simpler to
| distribute the driver as a library that software authors can
| include in their program. If there are several devices that
| work similarly but communicate differently, you could have one
| library that either includes multiple drivers, or exposes a
| common interface that other libraries can implement.
|
| A downside of any approach for USB devices on Linux that isn't
| a kernel driver is that one or more udev rules will need to be
| added (as the article described). This also applies when using
| a device that uses a supported USB protocol, but has different
| IDs than the ones listed in the kernel driver.
|
| [1] More devices fall into this category than you might expect.
| For example, Linux has an API for communicating with CAN
| devices called SocketCAN, so if you're writing a driver for a
| CAN device that connects via USB and exposes the full CAN bus
| over USB (maybe something that goes in or connects to a car),
| you should write a kernel driver that converts data between
| SocketCAN and whatever USB protocol is being used (assuming one
| doesn't already exist, a lot of USB CAN devices use protocols
| that already have drivers in the kernel). SocketCAN only
| exposes the raw data extracted from the CAN frames, so if you
| want to expose an easy way to control a particular CAN device,
| that belongs in a userspace library that uses the SocketCAN API
| under the hood.
| shreddit wrote:
| > Let's run it again to make sure it was not a fluke!
|
| I understood that reference
| 0xbadcafebee wrote:
| I want to run FreeBSD on my laptop, but they don't have a
| [complete] driver for my wifi card. I've thought about diving
| into AI coding-assistant agents just to see if I could use one to
| finish throwing together a working driver... but figuring out the
| AI agents is frictiony enough that I'm leaving it be. (I'm not a
| VSCode user)
| buildbot wrote:
| Claude code, being a CLI interface, might be more your style?
| Expensive though
| fithisux wrote:
| AI can also be used to help reverse engineer blobs.
| MobiusHorizons wrote:
| My understanding is that FreeBSD lacks the support for modern
| WiFi standards in any of its drivers, so it would be a
| significant effort of understanding the WiFi protocol in
| addition to understanding your specific device. That said,
| FreeBSD would be much easier to use on laptops if someone were
| to put in this effort
| LorenDB wrote:
| The author should probably have implemented support in OpenRGB
| instead to better benefit others, but this is cool nonetheless.
| jeroenhd wrote:
| I think they wrote the code more for the challenge of it than
| anything else. The final code doesn't seem to do more than the
| bare basics (which is probably enough for the author).
|
| Plus, to port this to OpenRGB, you'd need to rewrite the code
| into C++ (ugly, old C-inspired C++, at that: https://github.com
| /CalcProgrammer1/OpenRGB/blob/master/CONTR...) which would take
| most of the joy out of it for me at least.
| surajrmal wrote:
| I don't think the style described in that doc is at all ugly.
| It's practical and simple. I say this as someone who spends a
| lot of time writing modern c++ and heavily using templates.
|
| I thoroughly enjoy rust, but I doubt not being able to use it
| should be grounds for avoiding contributing to a project.
| Unless you are going to write async heavy code, libusb is
| pretty easy to use in C.
| fracus wrote:
| I wish this was done in C so I didn't have to learn Rust. But
| maybe it is time to learn Rust.
| dralley wrote:
| Rust isn't that difficult really. Easier in many ways than C if
| you're building normal software and not, like, a library of
| fancy data structures.
| jeroenhd wrote:
| This is using rusb, a Rust wrapper around libusb. libusb is
| still written in plain old C: https://libusb.info/
|
| If you don't want to learn a different programming language,
| you can take the exact same approach in any language you prefer
| and play along. You may need to turn the more object oriented
| calls into libusb_* calls, but if you're used to programming in
| C you probably won't have a problem getting that to work.
| VTimofeenko wrote:
| Excellent post! I have a Nanoleaf 3d thing that I was hoping to
| use as an ambilight-like thing for the TV, but the experience
| was... meh. I know about the Hyperion project and hope to set it
| up one day, but meanwhile I think I could try to repurpose this
| code to control the strip from a Linux box.
| rkagerer wrote:
| This is awesome!
|
| But it also makes me a little bit sad. The original parallel port
| and even ISA interface seemed so simple by comparison, with less
| layers of abstraction. Just run a wire, and write to a port.
|
| I remember when I was a kid, I found a breakout board in an
| electronics store's random clearance parts bin, with an ISA
| header on an edge. On a whim I took it home and wire-wrapped a
| 7-segment LED onto it. Power and ground were easy. Each segment
| was hooked to a data line, through a simple buffer IC. I cheated
| and used only a minimal number of address lines to feed the
| enable port (guessing through a simple AND gate or something). I
| was amazed when I wrote to that address and it worked the first
| time!
|
| I look at a protocol like USB, with hundreds of pages, and
| instead of that curious excitement and enablement I felt back
| then, I feel a bit overwhelmed.
| colechristensen wrote:
| I sometimes think about this, starting from scratch with a
| computer hardware and software stack that disallowed all of the
| layers of abstraction that have built up over the decades.
|
| Yeah many of the abstractions help with performance but maybe
| there's value giving up much of that performance in exchange
| for simplicity.
| rkagerer wrote:
| It would be neat to design a whole new contemporary stack
| from scratch.
| bzzzt wrote:
| It would also be an enormous undertaking, requiring man-
| centuries of work and has the risk of falling into the
| 'second systems effect' trap...
| dspillett wrote:
| For toy tinkering, to replicate something like the old
| ability to just write a byte to an IO memory location and
| have it appear on the pins of a parallel port, you could
| design a simple USB peripheral that did similar. Give it a
| set of DIP switches to pick a number (4 for 0-f, more would
| probably be overkill but feel free) and have the driver
| present something like /proc/simpleio/device<num>/in and
| /proc/simpleio/device<num>/out/pin<num> for reading &
| writing1. If you use the same set of pins for in and out,
| /proc/simpleio/device<num>/config to state which direction
| each is expected to work, and perhaps set voltage options
| (probably per device, per pin sounds overkill for this).
| Release the full design and let people make their own, sell
| pre-made boards and cases and/or let others do that (or just
| the boards and have people 3D-print their own cases). Devices
| could have as many pins as the maker likes.
|
| That would only cover the real basics: reading/writing the
| hi/low status of pins. Other things people might want is
| analogue voltage control/read (for many sensors) or pulse
| control (for controlling servos and such). Things like that
| could be mapped into the
| /proc/simpleio/device<num>/{in|out}/pin<num> files. Perhaps
| for setting/reading multiple pins at a time perhaps have
| something like /proc/simpleio/device<num>/{in|out}/allpins.
| You could expand the feature in many ways, though TBH beyond
| the simple hi/low thing people are probably better off
| getting an rPi or microcontroller and using all the available
| devices and plans there are out there already for their IO
| pins and using something newer.
|
| --------
|
| [1] Not sure what you'd do for Windows, I'd be inclined to
| release a Linux driver and let the Windows community worry
| about one for their platform.
| colechristensen wrote:
| USB parallel ports, data acquisition peripherals, or modern
| boards that run linux and have GPIO pins are already a
| thing and don't need to be created.
|
| What I'm talking about is a whole computer system + systems
| programming language + OS which is as simple to understand
| and program as computers were in the 80s. With modern
| speedups, without modern layers of abstraction.
| rkagerer wrote:
| Thanks for the info!
|
| I actually bought a real parallel port card years ago that
| plugs into a PCI port on my motherboard. Incidentally it
| also provides 4 serial ports.
|
| Only tried it on Windows, but it works great. If I recall
| there was some kind of library I have to use in modern
| Windows versions due to a permissions or kernel isolation
| thing.
| znpy wrote:
| > The original parallel port and even ISA interface seemed so
| simple by comparison, with less layers of abstraction. Just run
| a wire, and write to a port.
|
| All those layers of abstraction is likely what allows us to
| hook up a single wire to our laptops and get multiple very fast
| ports from the docking station along with power and display
| output.
|
| You get some, you lose some.
| vbezhenar wrote:
| USB is designed to solve a complex, but necessary problem.
|
| 1. Hot-plug.
|
| 2. High speeds with long cables of dubious quality.
|
| 3. Multiplexing multiple devices on a single wire with hubs.
|
| 4. Reliable transmission on lower layer, so higher level
| protocols don't need to worry about it.
|
| 5. Multiple speeds with negotiation.
|
| 6. Newer USB standards support multiple power voltages with
| negotiation.
|
| All that said, old USB protocols like USB 1.1 is not that hard.
| You don't need those hundreds of pages, only a subset of them.
| There are some tutorials in the Internets which will help you
| to understand everything, from wire signalling to application
| interface. Don't use USB reference as a learning source. These
| days ChatGPT probably will guide you over every layer. Just
| stick with old standards, they are simpler and plenty of
| devices use them.
|
| With enough persistence and some fast enough MCU you should be
| able to bit-bang USB 1.1 LS (1.5 Mbps) and write some simple
| USB device. That will require to implement all layers of USB
| and I'm pretty sure it's not impossible task.
| jeroenhd wrote:
| Serial ports still exist today. Even in desktop computers
| (though usually in weird underpowered ones designed for
| industrial applications and such). Even the most GAMING of
| motherboards have headers ready for one or even more serial
| ports to mess with. All you need is a cable and a card to slot
| into a PCIe bracket!
|
| USB itself, at least the 1.1 protocol that's still used for
| some devices today, isn't all that complicated in itself:
| https://youtu.be/wdgULBpRoXk
|
| Many if the complicated parts here, like device identifiers,
| are the things you'd need to manually configure if you were to
| use a serial port. Those hundreds of pages are similar to the
| hundreds of device types, vendors, and models that Windows
| would list when you clicked "add new hardware" back in Windows
| 98. When push comes to shove, you're just sending energy pulses
| down wires, there's just a chip in there that helps collect
| pulses so you don't need to manage the timing manually.
| dmonitor wrote:
| This is exactly the kind of simple tutorial I was looking for a
| few years ago. I forget what the project was that I wanted this
| for, though, haha. Thank you for the writeup!
| bhasi wrote:
| The title was misleading because the author wrote a userspace
| Rust driver and not a Linux kernel driver in C.
| amelius wrote:
| Upon reading the title I thought this was going to be about how
| easy it is to write or modify a Linux driver when using a LLM
| even if you know nothing about the subject.
| Neywiny wrote:
| No LLM needed. Kernel driver code for simple things is
| usually copy-paste-modify. Find something that works with an
| HID interrupt based device, and modify that. If you want a
| /sys led, copy from that. It's only if you try to push to
| mainline you need to worry about understanding it, but they'd
| probably smell LLM trash from miles away.
| fithisux wrote:
| There are many innovative OSes that are killed by the lack of
| Device Drivers.
|
| As a community we must find a way for tackling this issue.
|
| Micro-Kernels are a solution where one can run different OSes but
| they will reuse the same device driver servers.
|
| But it requires co-ordination and determination.
|
| Rust can be a solution for sure.
| jeroenhd wrote:
| Any programming language can be a solution, the programming
| language itself isn't the problem. Convincing device driver
| programmers around the world to come up with a universal API
| that includes all the possible features and works on every OS
| is.
|
| In this case, the cross-platform libusb should make this code
| work on either Linux or Windows (if you install the signed
| Windows drivers). If other operating systems port libusb, they
| get this code for free.
|
| Most "real" drivers still run in kernel mode, though, and not
| even Linux can keep their ABI stable (Windows has to, between
| releases, with the aid of compatibility wrappers that only work
| for a certain amount of releases).
|
| It would probably be worth it more forbBespoke operating
| systems to implement either the Windows API (like ReactOS does)
| or the Linux API (pick an LTS version) to get existing drivers
| to work. Unless you pay them, most driver programmers aren't
| going to bother with anything than Windows, maybe Linux,
| _possibly_ macOS.
| sumtechguy wrote:
| On a previous project I spent a lot of time trying to figure
| out a 'generic device driver'. That is actually a decently
| hard space to crack. As each device has randomly different
| ways of talking. Some are serial/local bus. Some are memory
| space. Some have a combination. Some systems broadcast data,
| some you have to query it, some you have to query then wait
| for the next broadcast. Some systems mildly follow the spec,
| some strictly follow it, some strictly follow their own
| flavor of the spec or an outdated one, some have their
| totally made up spec that they may or may not give you. Even
| from the same company you can have two models that on the
| outside if you use their stuff looks the same but under the
| hood is sorta different enough that your driver is garbage. I
| basically ended up here https://xkcd.com/927/
| yjftsjthsd-h wrote:
| Neither microkernels nor rust will help if you can't get
| everybody to agree on an ABI, which is the hard part in the
| first place.
|
| That said, if you're willing to deal with other people's APIs,
| NetBSD's rump kernels are good for providing reusable drivers,
| and some projects have even had luck pulling drivers out of
| Linux to reuse, though obviously that's a little bit touchier.
| amelius wrote:
| Does this provide protection against opening then device from two
| processes at the same time?
| yrro wrote:
| Does O_EXCL work with linux USB devices?
| blahgeek wrote:
| Given the title, I'm surprised (in a good way) that it's not
| about AI coding.
| Culonavirus wrote:
| I was kinda hopeful... I mean, letting an LLM write a driver,
| what could possibly go wrong :)
| rajiv256 wrote:
| Love it! I wrote an RTL8139 Ethernet driver in Rust as my
| undergrad thesis!
|
| With questionable grammar:
| [https://rajiv256.github.io//projects/ouros/](link)
| westurner wrote:
| Recommendations for a tutorial on how to write a formally
| verified kernel module in C? Rust?
|
| Are VFIO or eBPF sufficient; Does this code need to run in the
| kernel?
___________________________________________________________________
(page generated 2025-06-26 23:01 UTC)