I cloned my Debian 13 libvirt template VM and named the clone “occ”. This’ll be where I run weird OBD-II code without careful analysis.

You see, I decided to pivot away from SocketCAN/raw CAN and toward ELM327-based OBD-II diagnostics. Seems a bit easier to accomplish within the timebox. Besides, this way I can run ELM327-emulator in the VM, and run the DOS QEMU guest nested within the same VM. Keeps life simple. Once I’m done with OCC I just stop the VM. Libvirt rocks; just gotta read a lot of docs and books about it to fully understand its capabilities. It has a great Python API too, if shelling out to virsh won’t suffice.

I did eventually installed ELM327-emulator with some unforseen speed bumps. It needed an old version of setuptools because setup.py expects pkg_resources to exist, and that module was no longer present in pre-installed setuptools. ELM327-emulator runs runs, and I was able to connect to the ELM327 pseudoterminal via minicom or screen. Next I need to work out what the heck ELM327 commands look like. Stay tuned.

Figure 1: ELM327-emulator runs

Figure 1: ELM327-emulator runs

Updates from other OCC participants began trickling in. Some post on Gopher. Others post on Gemini. And of course some use plain old HTTP/HTTPS and HTML. Didn’t know of a Gopher or Gemini client off the top of my head. Then I recalled lynx. It does Gopher - yay! No Gemini support, however. But the good thing is this Gemini proxy portal exists and works with lynx: https://portal.mozz.us/. For example: http://portal.mozz.us/gemini/pv.smol.pub/occ-2026-day-3#old-computer-challenge-2026-day-3

Figure 2: Lynx viewing Gemini content via portal.mozz.us

Figure 2: Lynx viewing Gemini content via portal.mozz.us

Discussed possibly adding Gemini support to lynx. Funnily enough everyone assumed that I intended to upstream the code changes and go through all the gymnastics. Nah. I was just thinking I could vibecode it and circumvent the need for a Gemini portal. It is a means to an end. But for now, that portal.mozz.us seems to do the trick! ChatGPT came up with a couple things to check into, if I do choose to run a local dirty lynx tree. Any upstream contributions would not be vibecoded. The idea is to get this less-important code change done yesterday, not begin a multi-month upstreaming pilgrimage.

I’ve been busy too; can’t be bothered to plug leaks in the van, and it’s storming hard tonight. So I spent a bit of time cleaning up camp, wrapping the entire van in a tarp using tensioning knots that I recently learned. Then I drove up to Klondike to buy a large clothes trunk. Nice people. I appreciated the “God bless you” code switch experienced farther north. More neighborly, less adversarial to outsiders. They were super appreciative and gave me a bunch of other equipment (free of charge) which I have already put to use.

On my way back to camp, I stopped at a coffee shop, got distracted reading my localhost-hosted Wikipedia mirror, and spied a 3D-printed “check engine” light (CEL) keychain doodad. It seemed only fitting to obtain this trinket as an OCC keepsake.

Figure 3: Check engine light trinket

Figure 3: Check engine light trinket

Next up, prepare a FreeDOS image using virt-install or manually loading up a libvirt XML document to teach libvirt about the new VM. Then I’ll configure the libvirt VM to hook the local ELM327-emulator pseudoterminal in as a serial console. Finally I’ll code up something in DOS. I’m thinking a C-based DOS program that speaks ELM327’s higher-level OBD-II commands over the serial connection.

As a reminder, it’ll look like this:

DOS in QEMU ⬌ virtual serial/PTY plumbing ⬌ ELM327 emulator or device

Some OBD-II software tools to try with an ELM327 (excerpted from the ELM327-emulator readme):

I’m gassed. I’m going to take a nap.