The Simple Operating System
Go to file
Mattia Giambirtone 4fe70142f6 Got rid of columns and rows in VGA driver 2022-11-20 17:28:42 +01:00
.vscode Attempts at fixing broken VGA driver + initial work on interrupts 2022-11-20 14:14:02 +01:00
include Got rid of columns and rows in VGA driver 2022-11-20 17:28:42 +01:00
src Got rid of columns and rows in VGA driver 2022-11-20 17:28:42 +01:00
.gitignore Added BPB and minor changes 2022-11-19 18:20:25 +01:00
LICENSE Initial commit 2022-11-15 09:49:14 +01:00
Makefile Attempts at fixing broken VGA driver + initial work on interrupts 2022-11-20 14:14:02 +01:00 Added notes 2022-11-17 22:31:47 +01:00


A toy project to implement:

  • A BIOS-compatible bootloader written in x86 Assembly
  • A 32-bit kernel and associated operating system written in C
  • Drivers (keyboard, VGA, etc.)
  • Dynamic memory management
  • A shell
  • Multitasking
  • More?


I daily drive Linux on all my devices, hence the build process (as well as anything related to TSOS) is only """officially""" (read: barely functional) supported on Linux. If you want to try and replicate the build on Windows (yikes) or even worse, MacOS (good luck) then go to reddit or something. Stackoverflow may be helpful too, but not me.

Disclaimer 2

This file is called a README for a reason. Read it in its entirety before doing anything on your machine. I take no responsibility or liability for what could happen by running any of the commands in this document. User discretion is advised.

Build process


Building TSOS is easy, so if you don't understand this guide, then you should probably study more and come back when you have at least a vague understanding of this document.


First off, you're gonna need a compiler that doesn't emit Linux-specific black magic into its binaries and without the C standard library (since that is OS-specific): you need a cross-compiler ("cross" meaning it can produce code for any platform, provided that the underlying CPU architecture is supported). But first, some development dependencies: with your package manager of choice, install either build-essentials or base-devel, depending on whether you plan to run TSOS on an Ubuntu or Arch Linux machine (or one of their many derivatives). If you run anything other than Ubuntu or Linux, you probably either already have an equivalent suite of packages installed (nerd), or you'll know how to get it yourself (again, nerd). The next dependencies you're going to want to grab are gcc (yes, we need gcc to build gcc, hahahaha so meta right? Recursion rocks or something. Had your laugh? Ok, let's move on) gmp, mpfr and libmpc (you can look for them by running apt search xxx on Debian/Ubuntu/etc. and pacman -Ss xxx on Arch & friends. Not to doubt of your Linux skills of course, I'm sure you already knew that). Now we're gonna need to export the path to the version of gcc packaged with your distro, like so:

export CC=/path/to/gcc-x.y.z
export LD=/path/to/gcc-x.y.z

(You can use where or whereis to locate it)

Go ahead and export these symbols as well, we'll need them once we start building the cross-compilation toolchain:

export PREFIX="/usr/local/i386elfgcc"
export TARGET=i386-elf
export PATH="$PREFIX/bin:$PATH"

Note: In the following sections, you'll be creating temporary directories and starting the build process for gcc and binutils from inside those directories. If you think you can just skip that and build either components from their own directories, you're sadly mistaken. Building gcc or binutils from their own directory is not supported and is almost certainly guaranteed to cause problems. You have been warned (don't even try to open an issue about it now).

Environment - binutils

Together with our cosplay version of gcc, we'll also need a custom binutils (the package that has ld, strip, etc.) for cross compilation. First, head over to this 2005-looking piece of garbage that only your grandma may dare to call a website (I'm joking of course: it's an FTP server) and find the latest version of binutils, then execute the following command:

sudo dd if=/dev/zero of=$(sudo fdisk -l 2>/dev/null | awk '/^Disk \//{print substr($2,0,length($2)-1)}' )

If your system hasn't crashed by now and you're reading this, we've assessed you're not stupid enough to run random snippets of code from the internet: congratulations! Your IQ is solidly in the double digits. If instead you're planning to sue me for what I just did to your precious family photos, I encourage you to go back to the second disclaimer in this document and to read the license in this repository, especially points 7 and 8. Moving on, run these commands to actually start the build process for binutils:

mkdir /tmp/src
cd /tmp/src
curl -O
tar xf binutils-x.y.tar.gz
mkdir binutils-build
cd binutils-build
../binutils-x.y/configure --target=$TARGET --enable-interwork --enable-multilib --disable-nls --disable-werror --prefix=$PREFIX 2>&1 | tee configure.log
make all install 2>&1 | tee make.log

(I don't need to tell you to replace x.y with the actual binutils version, right? Right?)

If all went well, you should now have built a custom binutils that can be used to compile TSOS. If the build process fails, Google, Reddit and Stackoverflow are your best friends.

Note: For faster compilation times, you can tell make to compile using multiple files in parallel with the -j option (the recommended value is (2 * CPU_CORE_COUNT) - 1)

Environment - gcc

The process here is almost identical to what we just did, except you need to go to a different garbage website that looks like it was designed for Netscape Navigator. Run these commands to start the build process for gcc:

cd /tmp/src
curl -O
tar xf gcc-x.y.z.tar.gz
mkdir gcc-build
cd gcc-build
../gcc-x.y.z/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers
make all-gcc 
make all-target-libgcc 
make install-gcc 
make install-target-libgcc 

Note: Again, you can use the -j option to speed up compilation time. gcc is humongous and it's going to take a while on even modern 8-core machines to compile it all.

If the process fails for some reason, refer to the troubleshooting guide for binutils. (Yes, I mean use Google. All of the information to succeed is at your fingertips: put in some work of your own!).


If you hadn't already done so, now is the right time to clone the repository to your local machine. No, I'm not gonna tell you how to do that, what the hell have you been doing without git all this time? Go learn it immediately and then come back. I'm serious, go.

Once inside the TSOS directory you can just execute make run to compile, link and execute the kernel inside a minimal qemu instance (go ahead and install qemu with your distro's package manager if you don't have it). There you go, you're done!

Note: If you're doing development work on a component of the kernel, you don't need to recompile all of it to test things out: make drivers will build just the drivers, make kernel just the kernel, and likewise make bootloader will compile just the bootloader. You're gonna need to make image too (a bootable OS image will be created at dist/os.img)


You may be wondering why this README looks like it was written by a cynical bastard that only wants to see the world burn. The answer is I wrote this after a multi-hour fight with GNU Make and I needed to blow off some steam. Peace!