Lessons along the EndBOX journey
How a wild side-quest became the source of many of the articles you’ve read—and have come to expect—in this publication
About six months ago, during one of my long runs, I had a wild idea: what if I built an OS disk image that booted straight into EndBASIC, bundled it with a Raspberry Pi, a display, a custom 3D-printed case, and made a tiny, self-contained retro BASIC computer? Fast-forward to today and such an idea exists in the form of “the EndBOX prototype”!
This article isn’t the product announcement though—that’s elsewhere. What I want to do here is look back at the Blog System/5 articles I’ve written over the past months because what might have seemed like scattered topics were actually stepping stones toward the EndBOX.
Let’s look at what I learned along the way and why, even though developing EndBASIC may sound like a “useless waste of time”, it’s a great playground and the source of inspiration for the articles you’ve come to appreciate here.
“Porting the EndBASIC console to an LCD”
On April 26th, 2024
TL;DR: The article starts with an introduction to EndBASIC’s console framework and how I refactored it to separate display rendering primitives from higher-level operations. This design was inspired by NetBSD’s wscons, and the text explains how so. After that, the article continues to show how to extend the redesigned interface to talk to an SPI-attached LCD, how the SPI communication works, and how double-buffering and damage tracking allow for fast rendering performance.
Relevance: This is the article that started the EndBOX but I didn’t know it at the time. You’ll notice that the article ends with a list of parts to build your own embedded box… but because the software wasn’t readily available as a downloadable SD card image, I haven’t heard of anyone trying to use it at all.
Lessons learned:
SPI bus access: I had to reverse-engineer the sample C code that came with the ST7735s LCD, figure out how to access the SPI bus from Rust, and re-implement parts of it in my own terms. I also had to learn about DTB overlays because the SPI bus is disabled by default. I did not have to dive deep into DTBs at this point, but that came to bite me later.
Rasterization algorithms: Up until that point, EndBASIC had leveraged the SDL library and HTML canvas elements for graphics rendering. But when writing directly to an LCD… the only thing you can do is poke pixels. So I had to read on Bresenham’s line algorithm and the Midpoint circle algorithm, implement them and, of course, find a way to write unit tests.
“Revisiting the NetBSD build system”
On December 28th, 2024
TL;DR: The article presents a general overview of how the NetBSD build system shines in achieving cross-platform, cross-architecture, and root-less builds.
Relevance: I had to get back into NetBSD after many years of not touching it because its cross-building features were key to getting EndBOX up and running.
Lessons learned:
Not much has changed: This is more a realization than a lesson, but it was good to see that not much had changed since I used to use NetBSD on a daily basis. This is good because it shows how resilient BSD systems are, but also bad because some problems that made me leave NetBSD are still present.
NetBSD is still unique: I don’t know of any other OS that supports cross-building as trivially as NetBSD does, much less without requiring root access to generate disk images. I hear FreeBSD 15 will sport these same features, and that’s exiting, but “I’ll believe them when I see them”.
“Self-documenting Makefiles”
On January 10th, 2025
TL;DR: This article is a hands-on tutorial on how to write
Makefile
s that provide help messages by scanning their own content.Relevance: I had read about this idea before but had never put it to practice. In developing the EndBOX, I had to create a rather complex
Makefile
to glue together the patching of the NetBSD tree, the build of the NetBSD toolchain and release, the cross-compilation of EndBASIC for aarch64, and the bundling of all pieces together into a final disk image.Lessons learned:
Fragility: Implementing this idea is simple, but in the discussions that followed the article publication, I realized at least two problems: trailing space in variable assignments in
make
is meaningful and this approach cannot easily work if you have includes in yourMakefile
s. Not a big deal for my use case, but having practiced this, I know when and when not do retry this in the future.Use make and you’ll have a bad time: Nothing surprising here, but getting the
Makefile
to orchestrate all these disparate builds and to do it correctly without spurious rebuilds has been painful. What’s worse is that the resulting build process takes a long time becausemake
is unable to properly parallelize all build steps. It hurts to see my 72-core server “stall” when aconfigure
script runs.
“Hands-on graphics without X11”
On January 17th, 2025
TL;DR: This article presents a deep dive into NetBSD’s console drivers and how those can be used to render graphics directly to the framebuffer without relying on X11 or Wayland.
Relevance: Figuring this out was the key to unblocking the EndBOX project. I had built an earlier prototype of the OS image that used EndBASIC’s SDL console over X11 but… the boot times were atrocious and I wasn’t sure I could make them better. Researching how to leverage the framebuffer removed this roadblock as I could get graphics rendering almost immediately after the kernel finished booting.
Lessons learned:
wsdisplay and wskbd APIs: I had looked at the internals of these devices in the past but never paid much attention to the versatile APIs they expose. I had to do this now, and it was insightful.
gdb scripting: Nothing new (I knew this was possible), but I think it was the first time I put it into practice… for the article’s sake.
“ioctls from Rust”
On February 13th, 2025
TL;DR: An overview on what ioctls are and how to invoke them from Rust when bindings don’t yet exist for them.
Relevance: This was a direct follow-up to the previous article: that one was focused on gaining access to the framebuffer, which I prototyped from C, and this one was about productionizing those prototypes in the form of a Rust backend for EndBASIC’s console abstraction.
Lessons learned:
ioctl formats: Not all ioctls are the same. Some deal with simple data types whereas other deal with large structures—and the way they are expressed is different.
Integrating ioctls in Rust: This was “just a matter of programming”, but it was cool to see how the
nix
crate makes it easy to expose ioctls in a Rust-native manner so that they just look like function calls.
“Hardware discovery: ACPI & Device Tree”
On February 28th, 2025
TL;DR: A deep dive on how device discovery works on a modern machine, including details on ACPI and Device Tree, how they differ, and how they are put in memory so that the kernel can read them.
Relevance: During the development of the EndBOX, I had to enable SPI to render to the LCD via a DT overlay. I also had to find and install a DTB for the Raspberry Pi Zero 2 W so that NetBSD could boot on this board and so that the WiFi could work too.
Lessons learned:
ACPI and Device Tree: I pretty much knew nothing about these, so learning about the foundations behind them and how they differ was interesting on its own.
Device Tree overlays: I had to write an overlay from scratch to enable the SPI bus on NetBSD—and then get the LCD to actually work (which was its own time sink).
Linux vs. NetBSD DTBs: NetBSD reuses Linux DTBs, but NetBSD’s copy is ancient and contains local changes (to e.g. disable the unsupported Videocore). I had to figure out, through sweat and tears, how to port the DTB for the Pi Zero 2 W from Linux to NetBSD without breaking anything else.
“Beginning 3D printing”
On May 28th, 2025
TL;DR: A beginner-level introduction to 3D printing, including 3D modeling basics, slicing, and actual printing considerations.
Relevance: The final step in showing off the EndBOX was to create a case for it that matched the design I had envisioned months earlier.
Lessons learned:
Unprintable objects: The way 3D printers work imposes constraints on the kinds of items that can be printed, and I had to adjust my design a few times.
Modeling vs. slicing: They are two very different things, and I had never imagined that the second existed.
It’s not trivial: Even after figuring out the basics, getting a perfect print is difficult. I guess the real world is analog and subject to imperfections.
And that’s all for today. If you enjoyed any of these articles, it’s because working on the EndBOX gave me reasons to chase those topics down. To keep this kind of content going, I need time to play, explore, and tinker, so if you’d like to support the journey, please subscribe to or sponsor the project.
As for what’s next—well, I’m starting to rethink how I can apply the lessons of the EndBOX to something more impactful. Maybe it’s time to turn “just a fun ride” into something greater, because while BASIC may not be the future, the many components that have gone into building EndBASIC and the EndBOX may be. Stay tuned!