What does writing an operating system and software requirements have in common?
Nothing much at first glance, unless you have chosen a super difficult piece of software development to practice your requirements skills on. InstructionOS is precisely this: a 12-month learning project to write an operating system, which I’m halfway through.
I’ve been asked why I’m writing something that will never be used commercially; others have suggested I should focus less on software development if my profession is ‘business analysis’.
The truth is, working on something aspirational, super complex and far beyond your current understanding can be an incredibly useful experience. Not always easy, often incredibly challenging, but worthy nonetheless.
Complex projects, which building an OS from scratch qualifies as, aren’t just technically difficult but also challenging in many other ways. The approach to learning something completely new, technically very complex, and broad in scope (along with the necessary information management that comes with it) is a good example of something that needed mastering early on for the success of InstructionOS.
How will you discover what you don’t know, but need to know? How will you approach learning each new thing? How will you organise what you learn? How much should you learn at any one point? When do you revisit a specific topic? How many passes should you take? What information sources should you use? How do you validate what you discover? How do you not forget over an elapsed period of time? How do you successfully context switch?
Good questions I needed to answer before writing any code. I learnt that skimming across many things at a high-level, worked best for me when entering unfamiliar territory. Followed by successive ‘deep dives’ to elaborate certain topics. Rinse and repeat.
Bootloaders, x86 architecture, real/protected modes, CPU registers, BIOS functions, interrupt calls, segmented memory addressing, direct memory writes, framebuffers, C pointers, assembly, stack and heap allocation, make files, GCC, PE/ELF/bin formats, object linking, CPU emulators, Canadian cross-compiling, git branches and patching. Things I spent many months reading about in the evenings, over and over sometimes, not really understanding the detail, until one day it all just started to ‘click’.
What does any of this have to do with software requirements? A lot actually, the biggest thing being ‘how do you manage a roadmap and backlog for something very technical you don’t yet fully understand and can’t adequately define?’ A question I asked myself repeatedly, and sometimes struggled to answer. A question relevant to anyone developing new and innovative software. Hint: you need to think about defining outcomes and what you want to achieve, not spec’ing out low-level implementation details.
Example: prefer ‘wrap console output at line end’ rather than ‘row 1, column 0 double word VGA text mode character should be written to the zero-based, 80th framebuffer element’. The former leaves you free to experiment and enjoy coding each time you sit down to work on the project, the latter is fragile, restrictive and error-prone. It’s also more akin to putting on the enterprise shackles, but for free and in your spare time (nb. I tried both approaches).
Which brings me to perhaps the most important lesson I’ve learnt so far. Is your learning project interesting enough to sustain your attention through the setbacks, difficulties and challenges? Does the eventual outcome, or perhaps just the learning along the way, worthy enough to spend your precious life on it? (at the expense of all other things you could be doing)
InstructionOS, has been, and continues to be, sufficiently interesting and worthy enough for me to invest time in, moderately so. It had one false start, periods of intense technical up-skilling (I’m looking at you NASM), and a lot of soul-searching along the way. But it’s been worth it.