Writing a driver for undocumented hardware has always been a job of patience: capturing bus traffic, staring at hex dumps for hours, guessing what each register does and testing the hypotheses one by one, often for weeks. Christian Schaller, from GNOME, has published Using Artificial Intelligence to reverse engineer hardware, describing how he used Claude Code to do exactly that, and the result strikes me as one of the most concrete use cases for agents I’ve read lately.
A negative scanner with no support
It all starts with a box of old family photo negatives and a Plustek OpticFilm 8200i scanner, which in theory worked on Linux. The problem is that the manufacturer had changed the model’s chip without changing its name: the old one uses a Genesys GL845, already supported by SANE, and the new one a GL128, which isn’t.
The first attempt with Claude Code went nowhere and the project sat idle for a few months. What unblocked it was an idea from Tom Crider (GloriousEggroll), who had fixed a mouse driver by giving the agent full control of a Windows virtual machine. With that setup, a few hours later there was a first working scan on Linux, and a few days later a nearly complete driver, with support for the infrared channel.
The method: record from outside and compare
The part I like most is the method, which Schaller has packaged as hw-harness. The premise is simple: for almost any unsupported hardware there’s already a driver that works, the Windows one. You don’t need to read it or disassemble it, you just need to watch what it does.
flowchart LR
A["Windows driver · KVM VM"] --> B["USB device"]
C["Own driver · Linux"] --> B
B --> D["usbmon on the host"]
D --> E["Compare both captures"]
E --> F["List of driver bugs"]- Record a reference session. The vendor’s driver runs in a Windows virtual machine, with the real device passed through to it.
- Capture from outside. On the Linux host,
usbmonrecords all USB traffic. It sits below the layer that passes the device to the virtual machine, so Windows doesn’t notice. - Repeat the same operation on Linux with your own driver, and capture it the same way.
- Compare both captures. Since they come from the same tool, they can be compared directly, and the differences are the list of driver bugs.
For hardware with no bus to listen to, like a camera built into a laptop over MIPI, the virtual machine is still the source of information, but through INF files, the Windows registry and the ACPI tables.
The repository includes several tools for the agent: winctl to drive the virtual machine over SSH and RDP (including clicks and screenshots), usbcap to capture with usbmon, hostdev to move the device from the host to the virtual machine and back, and hwdbg for debugging on Linux with scoped root permissions. With that, the agent can drive the vendor’s app, scan on Windows, hand the scanner back to Linux and repeat the test without anyone touching anything.
Observe, don’t decompile
There’s an important detail, which the project documents separately: hw-harness deliberately stays on the observation side. Traffic captures, descriptors, INF files, the registry or ACPI tables describe the hardware. Disassembling the vendor’s driver is something else, with different legal consequences. So every constant in the new driver comes from something that was recorded, not from copied code.
It’s the classic clean-room approach to reverse engineering, except that now the tedious part is done by the agent.
Three projects
Three projects came out of this method:
| Project | What it does |
|---|---|
| SANE backend for the OpticFilm 8200i | Color, gray and infrared, from 300 to 7200 dpi, at 8 or 16 bits, with dust removal using the infrared channel |
| Negative Vibes | GNOME app in Rust for scanning negatives and slides, with non-destructive settings and IT8 calibration |
| MIPI camera fixes | Kernel and libcamera patches for a ThinkPad X1 Carbon Gen 14 |
The scanner story has a touch of irony: while the project was on hold, someone added support for that scanner to SANE’s genesys backend, in September 2026. Schaller compared them: both resolve the same detail at 3600 dpi, his is faster at full resolution (34.6 s against 54.4 s) and has infrared cleaning, and the upstream one offers more resolutions. He presents it as a proof of concept and expects to use the upstream driver once it reaches parity, but the findings may help improve it.
The laptop camera
The camera case seems the most interesting to me, because there’s no USB bus to listen to. The ThinkPad’s camera uses a Sony IMX471 sensor behind an Intel IPU7, and on Linux it produced dark images, with very dim corners and a yellow-green cast. In one day of agent work, reusing the same setup, these fixes came out:
- In the kernel driver: a bug in crop selection returned an error before storing the rectangle, the test-pattern register had the wrong width, and the analogue gain cap was too low, which cost about 1.8 stops of sensitivity.
- In libcamera’s software ISP: lens shading correction was missing, leaving the corners about 2.7 stops darker. On top of that, white-balance statistics were summed at the sensor’s native bit depth against an 8-bit black level. This last fix applies to any RAW10 or RAW12 sensor, not just this laptop.
In a low-light test, average frame brightness went from 31.1 to 90.9, and colours ended up close to those of a USB webcam used as a reference. Having that webcam connected at the same time was key here, so the agent could compare both images. The kernel patches have already been submitted and the libcamera ones are under review.
My takeaway
Schaller sums up what he learned in three ideas, and I share them:
- A reference capture changes everything. Comparing a working trace with a failing one turns “it doesn’t work” into a concrete list of differences.
- AI is good at the tedium. Reading thousands of lines of USB capture, noticing that a sequence repeats with one byte changing, proposing what that byte means and writing the test to confirm it. And it doesn’t get bored.
- Real hardware is the only judge. Everything was checked on the actual scanner and laptop, and the person is still the one deciding what to build and holding the device.
What I like most about this case is that it isn’t about the agent writing code better than a person, but about giving it a very clear verification loop: there’s a working reference, the difference can be measured and the result can be checked on the hardware. It ties in with what I wrote a few days ago about the code review bottleneck: if reviewing what an agent produces is what slows things down, what helps most is having automatic, objective ways to check that the result is correct.
Schaller himself admits he lacked the in-depth knowledge this kind of work usually demands, and that neither the scanner nor the camera is perfect. But hardware support has always been one of Linux’s weak spots, and if the heavy lifting of reverse engineering becomes affordable, it could reach far more hardware than the few specialists who do this today can cover.
Source: Using Artificial Intelligence to reverse engineer hardware, Christian F.K. Schaller.




