Metal ARM: Introduction

The majority of my software career has been spent at what I'd call the "infrastructure" layer: programs that sit somewhere between the kernel and an application's backend, and upon which other applications or systems are built. I've also occasionally done some UI work, but I've never gotten (or taken) the opportunity to go lower in the stack.

I've had the increasing feeling, though, that it's time to go to the bottom and work my way up. I think there are a few contributing factors to this, but a major one is that most infrastructure software is still firmly in "victim" territory. It's subject to external factors that seem completely irrelevant to the problems I work on, and yet they exert a large influence over the solutions I'm able to build.

The environments my code lives in, the tools I use, the data formats and protocols I communicate with, they're all (for the most part) inherited. And it's not that they're all the best, or even necessarily good. Some things are just accidents of history - they're what stuck at the time they were developed (and of course some of them are actually good).

Before I go further, let me say that I respect both the relative immaturity of our field and the general complexity that arises from trying to model a process with code. It's hard, even humiliatingly difficult sometimes, to take an observed process in the world and try to codify it. Interesting and useful stuff gets built, no doubt, and we've been able to extract value (for some definition of it) with what we have, but sometimes it feels like we're just way off base. We build on the layers that calcified in the previous generations, yet notwithstanding all the advances of the last 70 or so years, our tools still feel decidedly primitive at best, and hilariously unsuited at worst, to solving the programming tasks before us. But it's hard, and I'm aware of that.

Where I'm Going

So I recently started two projects as an attempt to make some personal progress. First, I want to see just how complicated it is to build a software stack "from scratch" (with a healthy dose of caveats). Second, I want to use this stack to interact with real hardware and learn about the implications that hardware imposes on software. Third, I want to find a way to push the state of programming forward, even if it's a very small step.

The projects are metal-arm (hence the name of this series) and chasm-toolchain. Metal-arm is my foray into the world of bare-metal development, starting with handwritten machine code and ending with something like a small hobby OS. Chasm is the toolchain on which metal-arm is built. As I learn about an embedded/bare-metal concept, I'll first implement it by hand, and then add support to whatever part of the chasm toolchain is needed for that feature. I then sanity-check the chasm implementation against my handwritten version on real hardware, and rinse and repeat.

There will be mistakes, inefficiencies, and hours of staring at machine code, yes, but there will also be a toolchain that stands on its own, tons of learning, and perhaps a few neat features that are hard to find in more mainstream stacks. If that sort of thing interests you, I invite you to follow along with this series!

As always, feel free to reach out on GitHub with questions and critiques.