Writing Your Own Operating System
It is the dream of every soon-to-be OS developer to become the next Bill Gates, Steve Jobs, or Linus Torvalds; and it is the duty of everyone in this seemingly 'elite' community to dash all your hopes and dreams with a healthy dose of reality. Your operating system will probably not even attain the commercial success of the Edsel or Betamax. Many are inspired by Linux, however, Linux was based on software already decades into development, supported by many individuals from the staff at U.C. Berkley to the legendary Richard Stallman, and Linux itself has been in mainstream usage for several decades. In that time, the user base has grown, and thousands of programmers have contributed to it; the kernel codebase alone has grown from a few hundred thousand lines of code to well over 20 million! That doesn't include all the supporting software or drivers either!
If you're reading this hoping to find commercial success, you'd be far better off forking Linux and creating your own distribution. If however, you are interested in OS Development as a means of continuing education, read on!
Benefits of Writing an OS From Scratch
While the likelihood of you achieving commercial success of any significance with a custom OS and kernel is extremely low, there is a multitude of benefits and rewards to reap from making one:
- Bragging Rights
Setting out upon the monumental task of writing an Operating System places you among a small, elite group of individuals. Just booting into your first kernel is an engineering feat. Your non-tech friends most likely already think you're amazing with computers; when they learn you wrote your own OS from scratch, they're going to assume your hacker level is over 9,000. Your geek friends will envy and idolize you, and, perhaps most importantly, you'll get to make new friends in the hobbyist OS Dev community that you can learn from.
I have spent YEARS trying to get a job in the software industry, and with all the outsourcing we've experienced, it is very difficult to find a job as a programmer, especially without a four-year degree. After starting my DIY operating system, I've seen some serious interest from firmware companies and offers of employment pending my first semester at college. Surprisingly, it has also helped with non-tech jobs; every recruiter I have talked to has been impressed and wanted to know more - a few have even asked me to help them with their computers in the middle of the interview. Writing an operating system definitely increases your marketability and showcases your skills to potential recruiters, and the experience you gain from it will help you contribute to open source projects.
Among general programming skills, you'll also gain a solid understanding of some pretty difficult topics like memory management, process scheduling, interrupts, and resource sharing. Perhaps most importantly, you will learn to debug without a debugger which is a very useful skill to have. In short, everything you do with computers after this will be immeasurably improved by the experience gained from creating your own OS. It will remove the 'magic' from computers, and you'll be able to grasp a much wider variety of subjects than you did before.
What It Takes
Writing an operating system is not an easy task by any means. On the contrary, it is considered to be one of the most challenging and difficult programming tasks in existence. You have to interact with hardware from a variety of vendors that may or may not be well documented and in some cases, hardware that does not follow the standards outlined in the developer guides. The knowledge requirements to write an operating system really vary on the individual's capacity for learning, but in general, it is inadvisable to write an operating system until you're competent in the following:
- Fluency in the English Language
Virtually every developer guide, tutorial, academic paper, etc., is written in English. It is critical to be proficient; being able to read and write in English is the most important skill. If you are able to read/write English but are not quite fluent, it is possible you'll be able to write an OS, however, you will be at a severe disadvantage over a native or fluent speaker.
- Programming Experience
Ideally, you want years of C and assembly programming experience before tackling the task of writing an OS. There have been exceptions to this rule (myself included) that started with little to no experience in these languages; however, I started coding, building robots, and programming microcontrollers before I was 12, had over a decade of experience in python and ASIC languages and had started learning ASM and C around 8 months before I started development on my first kernel. The language is a little important but not as important as understanding the logic of programs.
- Proficiency in Linux/Unix
You need to have a Unix-based operating system to develop with. OSX, BSD, or Linux. Windows can be used, but you still need proficiency and an understanding of Unix because almost all of the tools you'll be using were created on Unix! It's really not that hard, though, and I'll walk you through some of your options in an upcoming article if you're not already using a Unix-based OS.
- Knowledge of Computer Science
Little life tip here, free of charge: generally, it's a good idea to have at least a basic understanding of what you're going to do before you do it. You should, at a minimum, understand boolean logic, the binary and hexadecimal number system, how memory is stored, logic gates, and ideally, you'd be able to build an ALU. A basic understanding of calculus is also helpful.
- Research Skills
Good research skills are essential. Nobody knows everything that is needed to be known about Operating Systems; it's impossible. You have to work closely with a variety of hardware, software, and industry standards that you likely have never even heard of. More than just having google-fu, you have to be able to sift through mountains of frivolous information to find the little nuggets of knowledge needed to accomplish your task. The Intel developer manuals alone have over 4,000 pages, and the processor is hardly the only hardware you'll be working with.
Mistakes I Have Made
There are quite a few mistakes I have personally made since starting down the path of developing my own operating system; everyone will eventually face issues writing their own OS, and nobody is going to make a perfect OS on the first try, but as long as you stick with it, work through your mistakes, and learn from them you'll be fine.
- Lack of Experience
I've been programming various scripts for around a decade now (I started very young), but Q-Basic and Python do not an OS-Dev make. I started experimenting with assembly about a year before I started my OS project, and I had never touched C prior, but some python did transfer over, thankfully.
- Lack of Direction
I didn't (and still don't) have a well-defined plan in place. This was due to my lack of experience and impatience. Had I taken the time to research everything needed to make an OS before I started coding, I probably would not be writing this article right now! That said, it was a fatal mistake. Already I have had to rewrite the kernel several times to account for things I didn't know about, including basic topics like the Global Descriptor Table.
- Frankenstein Code
In my initial rush to 'make something work', I found myself copying the work of other OS Developers; there's nothing inherently wrong with this (unless you're trying to sell it as your own), but if you just copy and paste the code you will never make a bootable operating system. At some point, you are going to run into a wall and actually have to learn what you're doing. That means busting out the debugger, reviewing processor architecture manuals, lots of experimentation, and eventually having to rewrite the code you borrowed to begin with.
- Failure to Document
Good coding practice dictates you document why you're doing what you're doing, yet often on personal projects, we tend to be laxer with this. That is not something you want to do with a large project like this; I cannot tell you the number of times I have gone back over old code and stared blankly at the screen, wondering what the heck was going on. Then you try to 'fix it' and wind up breaking 12 things down the line. This is not good. Even Linus made this mistake in the early days, and to this day, the Linux kernel developers are still retroactively documenting the kernel. Start documentation from day 1- you won't regret it.
- Not Following POSIX
This is definitely more of a 'preference' and design consideration, but I consider not following POSIX from the beginning the biggest mistake I have made thus far. As it is now, I have to make everything from scratch; porting any software requires significant effort to either rewrite the software or modify the kernel to support the software.
- Taking the Easy Way Out
Again, in my rush to 'get it done,' I sought out the easiest way to complete tasks which got me a short way, but all that work had to be redone later. For instance, I decided to write my own bootloader because I was scared to learn how to use GRUB, this set me back weeks in production as I wrote a bootloader entirely in assembly and had to create each new ISO completely by hand instead of taking advantage of the grub-mkrescue command. Ultimately, I wound up using GRUB anyway - and added multiboot compatibility to my kernel with far better results than I could have achieved with my DIY bootloader. Sometimes the "harder" way to do something is actually easier in the long run; in fact, it often is.
All in all, the mistakes I made were generally a result of rushing production; on the flip side, these blunders were important to make. Even if you heed my advice, you will make a lot of mistakes of your own, but that's part of the learning process and what makes this project so exciting and challenging.
There is a lot of material to cover and a berth of terminology I used that some people will not understand. Unfortunately, this will be the case for nearly every resource you find on the topic, as operating system development rarely strays from the realm of academics, and it would be a disservice to you, the reader, to even try defining some of the terms in this brief introduction; the likelihood of misunderstanding vital concepts is too great to ignore.
© 2018 Noah G Wood