Going Native
Inside the Computer⌗
I recently changed roles to become an embedded software engineer. I gave up managing a team of SREs to return to working on software. Is it a step down? Maybe. But, frankly, I don’t care. I’m still paid the same. I just don’t have “Manager” on my title.
As an SRE I worked on software running on the computer. There are teams that deploy the physical server. Other teams add a management layer to it. Then an OS layer, managed by the OS team. Then the cloud management tools in the OS, managed by various teams. Other teams then manage the VM running on the operating system. Then the cloud management tools in the VM, from that team. And then, finally, the software my team and I managed. Which, by the way, talked to the cloud management tools so that our end-customers can provision a VM.
That’s software running ON a computer. I’m working on the software running IN the computer. It’s loaded into some non-volatile memory. On startup the program counter jumps to that address. And away we go at just over 1 Ghz! There is nothing between my code and the CPU. There’s no place in memory that I can’t touch.
It strangely reminds me of the early days of computers. Back then, the OS was really simple. It really did nothing more than conveniently launch programs. When your code ran, you had access to the entire machine. If you wanted to use the serial port on the machine, you used the serial port. You did not ask an operating system for the right to send it serial port commands. You wanted to write a game? You compile in or write a driver for the graphics card, to which you have full access.
Don’t get me wrong. For general purpose computing that’s a categorically worse model. Programs have bugs. Games have bugs. I used to restart my Compaq Deskpro on a regular basis. I made a lot of bugs, learning to code on a System 7 Mac. Fortunately, Apples came with a programmer’s reset button on the back. Because one little mistake and I might freeze my machine. Maybe now. Maybe in an hour.
But it’s fun to have the whole machine. Want to use the serial port? (Known as UARTs.) You write to a registers that control the port. Then you read and write to registers that receive and send data. Sometimes the system vendor provides a set of “drivers” that encapsulate that logic.
It takes me way back, but in a good way. Today’s tools are so much better than the tools I had then. Those tools consisted of a text editor (no syntax high-lighting), the compiler, and sometimes a good debugger. And mostly me running the code in my head to debug problems. That’s the game and puzzle part I like to solve. The true joy of putting something together in your head, building it, and seeing it execute.
What I don’t like is slogging through configuration files to fix CI/CD pipeline. Pulling my hair out, after following the docs and stack overflow, why that pipeline is choking on line 1,648 in an automatically generated YAML file. Oh, wait, it wasn’t really the YAML file? That’s a red herring? I need to update what cert?
The tools today are generations better. I have linters and analyzers to check my code for many types of issues. I have awesome debuggers. My compiler flags all the problems that gave me heart-burn. It’s still no bed of roses. And I still have to ‘run code in my head.’ But it’s real programming. And it’s fun.