“Congratulations, its a baby [operating system]!” : The Basic Tenets of Creating Your Own Operating System

Thanks to the beauty of the open source, it is now within the grasp of anyone with the right know how to create a custom operation system based on open source code. Basically,what this essentially means, is that you can make your own Linux, or BSD, or Hurd based operating system (your own distribution)! I have recently made a bare boned operating system (which I dubbed Kevix 🙂 ) so that I could learn more about operating system internals. I will go over in generalities about how an operating system is born, and then guide you to resources so you can actually get down to making your own operating system. So, how exactly do you even get started with making your own operating system?

There are few concepts that are helpful to have in mind. Firstly, an operating system is a functioning, interweaved system of software that enables a computer to function up to modern standards and it can operate without relying on code outside of the computer’s system. This complex system of software is a familiar concept. Everyone who uses a computer has some notion of software working together to make the computer run. However, much of the underlying, nitty-gritty system internals are purposefully hidden from the user. To get a better grip on how things have to be configured, you have to understand how programs execute. Modern programs are linked against libraries, shared chunks of code that make programming easier, and conserves disk space. For instance, your favorite music player program contains no code for allocating system memory. Rather, it contains code for calling a library that allocates memory for the program. Likewise many other important functions of a program are contained in these shared system libraries. In order to call these library functions though, the program must know where the shared library is in the filesystem by being ‘linked’ to the library. In Linux, run ldd ./{any binary executable} and the computer will tell you what libraries that executable is linked to. This list can be very large for some programs. As a final note, it is also important to realize that there some files on the system are simply text files used to configure programs and store data. Now we should have all the knowledge we need to know to start building our operating system.

Alright, so our goal is to make a working system of properly linked executables that can run a computer’s hardware without relying on anything outside the machine system. Our new system will be built on its own partition. Nothing outside this partition can be used to make the system work. For instance, you don’t want to have to compile code for your system on another computer, you want your system to be self contained! This independence is tricky to achieve. If you’re familiar with creating binaries, you know you need a compiler to take human generated code and turn it into machine-usable code, as well as taking care of linking the binary to what it needs to run. Our new system needs a way to be able to create code, it needs a way to compile and link its own executables. The compiler essentially, is the starting point, the basis, of the new operating system. We need to find a way to compile a compiler. The trickiest part about compiling a new compiler is that the new compiler toolchain cannot have any of its links referring to the first compiler toolchain. The method of doing this is to use a host system’s compiler to create the new compiler we need for our new system. In order to break all of these links effectively, and create an independent compiler, it is best to use an intermediary toolchain, a compiler system that is separate from the first one, but is independent in as many ways as possible. Using this intermediary toolchain, we can sucessfully build a compiler that exists in and of itself. This is the key. The new compiler exists and needs only its own code to function. Once we have a new, independent compiler, we can build whatever we need in our new system.

So at this point we have a working way to create machine code for whatever we want. If you’ve ever used a Linux system before, you know that there are common, universal utilities that are standard and necessary for a complete system. There are well defined standards for Linux systems that are generally a good idea to follow. Luckily the standards and all the source to Linux’s system tools are all freely available and actively maintained. The next step is to build all of these and install them into your system. In this step, everything you want on your system is compiled and installed. Programs like ls, cat, grep, X11, Gnome/KDE, ifconfig and all the other programs used in your custom system are created and configured here. This process honestly teaches you so much about the way your system is set up. You begin to get a feel for what is in charge of doing what in a system, and you learn about linker and shell paths, and lots of things like that in the process. There might be some reading of documentation necessary, but you will be better for it in the end. We’re creating our own operating system, a little work is definitely required! After this [potentially long] task is complete we have a working system of programs that don’t know how to start up or operate anything. Now we need to put in a kernel.

Installing the kernel is surprisingly easy. It is pretty much the same process as building all of the rest of the system. The critical step is the configuration of the kernel to your system. If your aim is to create a generic kernel, it is probably best to just build as much into your kernel as you can. For efficiency’s sake though, it is better to select only what you need to include in the kernel so that your machine will boot and run everything. Use the kernel configuration tool with make menuconfig. You can then select exactly what you want and need in a kernel. A lot of the options are self explanatory, but some require some learning to see what they do. After the new kernel is done compiling, you’re almost ready to boot into your new system. Write an entry for your new system in GRUB and you’re ready to boot up into your brand new custom system!

Once your system starts up, you’ll notice its very bare-boned. Much more work is needed to get complex graphical environments running. Compiling all this code for graphical interfaces and the like that you use everyday has made me have a greater appreciation for distribution maintainers, and taught me much about Linux’s internals. You also learn what every file and things like bonobo (for GNOME) or DBUS does.

I realize that this article is very general, and only goes over the concepts of creating your own operating system. Luckily for us, there is a great and active project out there called Linux From Scratch. This is a how to guide in book form that uses the same principles outlined in this article. Download the LFS book (pdf , html, or xml) and all the code required, and you’re well on your way to making your own distro. However, even after successfully completing the LFS book, you will still have to go through installing lots of packages in the Beyond Linux From Scratch book to have a system that is anything other than a bare bones operating system. BLFS guides you through installing things like graphical interfaces or some utilities that are optional. A word of fair warning, this whole process is not for the faint of heart, but you honestly learn so much about how operating systems work, and I highly advise it. Good luck! 😀

Edit: Thanks to anzanhoshinroshi for pointing out that: Tenet= basic principle. Tenant: One who is renting a property.  😀

This entry was posted in Coding, Open Source. Bookmark the permalink.

2 Responses to “Congratulations, its a baby [operating system]!” : The Basic Tenets of Creating Your Own Operating System

  1. i did not understand anything

    can u please make it a little bit more clear to me??

Leave a Reply

Your email address will not be published. Required fields are marked *