Operating System Development from Scratch – Part 1

in computer •  10 months ago 

Hello everybody, it’s me, Lovelace. Welcome to the first part of a complete series of guides about Operating System development.

I have been studying operating systems and operating system development for quite a bit now (not for that long, yet I still have some experience with it). Operating systems is – probably – one of the most complicated projects a programmer can start working in, but it is one of most rewarding, as you literally get to manage the resources of a real device, which feels so incredible, trust me.

I am currently working in a kernel called Kinl, all these guides (I have planned to do more than one) will be based on the code and the things that I learn with Kinl, I have been working in it since June 2021 – or so – but I started rewriting it a few days ago because I have learned a lot of things that I wanted to implement in Kinl.

As mentioned before, this is one of the most complicated projects you will code, therefore if you are a beginner you shouldn’t try doing this (even though you could read the theory so you keep getting ready for the day you can actually start implementing an OS by yourself). The only requirements I’d ask you for is to be proficient with the Assembly and C programming language, I’ll be using the NASM assembler, there’s no need for you to already know about operating systems, all the concepts about them will be taught in these guides. In this first entry, I had planned to help you set up a development environment in your computer and tell you about the things that your operating system will have at the time of completing all these lessons, so let’s go ahead with them.

On completion, your operating system will have:

Your own bootloader: this is a little program that will load your operating system from disk to memory, this is the first program that gets executed when a computer boots.

  • Enabled A20 Line: that allows you to access all memory.
  • An operating system in protected mode: which is the main mode of a processor in which operating systems are run.
  • A graphical operating system: so you can draw shapes, text and even images with your operating system.
  • An implementation of the heap: so memory can be dynamically allocated and freed.
  • Paging.
  • Support for the FAT-16 filesystem.
  • Tasks and processes.
  • Implemented userland.
  • Implemented the interrupt 0x80.
  • Write a keyboard and mouse driver.
  • A working elf loader.
  • The basis for writing a C stdlib.
  • A shell that will be able to run programs and pass arguments to it.
  • Simple multitasking.

That should have motivated you enough to start reading all these guides, there are a lot of complicated topics that I would have loved to find when I was just starting to develop kernels.

Building a Cross-Compiler

One of the things that we will need to create our own kernel, is a cross-compiler, as it will let us compile our code without any headers or any os-dependant header, for example.

Note: all these instructions will be written for a Unix-like environment, if you are not using an environment based on Unix to develop, please get one before continuing with these guides. Before compiling our cross-compiler, we will need to download some dependencies:

  # For Arch
  pacman -Syu base-devel gmp libmpc mpfr

  # For Debian-based distributions
  apt install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo libcloog-isl-dev libisl-dev

  # For Gentoo
  emerge --ask sys-devel/gcc sys-devel/make sys-devel/flex dev-libs/gmp dev-libs/mpc dev-libs/mpfr sys-apps/texinfo dev-libs/cloog dev-libs/isl

  # For Fedora
  dnf install gcc gcc-c++ make bison flex gmp-devel libmpc-devel mpfr-devel texinfo cloog-devel isl-devel

  # For OpenBSD
  pkg_add gmp libmpc mpfr texinfo

Now, you’ll need to download the source code of both Binutils and GCC. You can do so by executing these commands:

  mkdir ~/src
  cd ~/src
  wget https://ftp.gnu.org/gnu/binutils/binutils-2.37.tar.xz
  tar xvf binutils-2.37.tar.xz
  mv binutils-2.37 binutils
  wget https://ftp.gnu.org/gnu/gcc/gcc-11.2.0/gcc-11.2.0.tar.gz
  tar xvf gcc-11.2.0.tar.gz
  mv gcc-11.2.0.tar.gz gcc

  mkdir -p ~/opt/cross

Before we get to compiling Binutils and GCC, we first need to export some variables so we can use them later at the moment of compiling:

  export PREFIX="$HOME/opt/cross"
  export TARGET=i686-elf
  export PATH="$PREFIX/bin:$PATH"

Now, we can compile Binutils:

  cd $HOME/src

  mkdir build-binutils
  cd build-binutils

  ../binutils/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
  make install

And now, we can build GCC:

  cd $HOME/src

  which -- $TARGET-as || echo $TARGET-as is not in the PATH

  mkdir build-gcc
  cd build-gcc
  ../gcc/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
  make all-gcc
  make all-target-libgcc
  make install-gcc
  make install-target-libgcc

Once it is finished compiling, we can use both our “naked” Binutils, and GCC. Reference for building the Cross-Compiler: wiki.osdev.org.

That was it for this first guide, I just wanted to talk a little about what you will learn and setup the cross-compiler so when we start writing C code, we won’t have to worry about it anymore.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  


Your post has been upvoted by @zero-to-infinity. We are supporting all the STEM Content Publish in Steemit.

For more,you can visit this community


Support us by delegating STEEM POWER.
20 SP50 SP100 SP250 SP500 SP

Follow @zero-to-infinity & @steemitblog for latest updates

Nice, everything is well explained!