Implementing an Operating System #1

Tharushi Chamalsha
5 min readJul 16, 2021

Implementing an operating system is not an easy task. We can’t even think of a way to begin the problem.

Here I’m going to let you know from the first step. Take your time and read the article carefully and then you will be able to implement your own operating system.

Step 1

I am going to use a virtual machine with ubuntu installed to develop the operating system. You can download the virtual box using the following link.

VirtualBox is basically inception for your computer. You can use VirtualBox to run entire sandboxed operating systems within your own computer. Users of VirtualBox can load multiple guest OSes under a single host operating system (host OS). Each guest can be started, paused, and stopped independently within its own Virtual machine.

Step 2

Then you have to install Ubuntu to the virtual box you have got in your machine.

Ubuntu is open-source software which you can download easily from the internet. Since its customizable most of the developers use Ubuntu as their operating system. The Ubuntu desktop is easy to use, easy to install, and includes everything you need to run. So let's use the Ubuntu desktop version for this task.

Use the above link to download the Ubuntu iso file to your machine. Then install ubuntu to the virtual box as well.

Ubuntu installed in Virtual Box

Now you are ready to implement your OS. Let’s start the journey!!

Step 3

Step A:

You have to install the necessary packages(build-essential, nasm, genisoimage, bachs) once Ubuntu has been installed to the virtual box. Open up the ubuntu terminal and execute the following code. Then the required packages will be installed on the OS.

sudo apt-get install build-essential nasm genisoimage bochs bochs-sdl

This is how the terminal will look like when you execute the command

Build-essential packages are meta-packages that are necessary for compiling software. They include the GNU debugger, g++/GNU compiler collection, and some more tools and libraries that are required to compile a program.

nasm: Since we are using assembly, we have to use nasm(Netwide Assembler) to compile assembly programs.

genisoimage is used to generate an ISO image file for the file system.

Bochs is an emulator which is used to develop operating systems. When an emulated operating system crashes, it does not crash the host operating system, so the emulated OS can be debugged.

Step B:

Now you have to save the following code segment inside the loader.s file. You can use the terminal to create files or manually create files inside the directory you will have your os.

Use touch command to create files inside your directory

Now paste the following code segment to the file you have created.

loader.s

The file loader.s can be compiled into a 32 bits ELF [18] object file with the following command:

nasm -f elf32 loader.s

Step c:

Now, GRUB needs to load the Kernel into the memory. In order to do that, we will be using the following code.

link.ld

You should save the above code inside link.ld file and execute following command in order to link the file.

ld -T link.ld -melf_i386 loader.o -o kernel.elf

Now there will be a file called kernel.elf inside the directory.

Now you should copy the downloaded file (stage2_eltorito) into the directory and the directory should look like this now.

Step d:

We will create the kernel ISO image with the program genisoimage. A folder must first be created that contains the files that will be on the ISO image. The following commands create the folder and copy the files to their correct places.

   mkdir -p iso/boot/grub              # create the folder structure
cp stage2_eltorito iso/boot/grub/ # copy the bootloader
cp kernel.elf iso/boot/ # copy the kernel

A configuration file for GRUB must be created to tell the GRUB where the kernel is located and configures some options.

menu.lst

You should place menu.lst inside the folder iso/boot/grub/ . The contents of the iso folder should now look like the following figure:

iso
|-- boot
|-- grub
| |-- menu.lst
| |-- stage2_eltorito
|-- kernel.elf

Then you can generate ISO image using following code segment.

genisoimage -R                              \
-b boot/grub/stage2_eltorito \
-no-emul-boot \
-boot-load-size 4 \
-A os \
-input-charset utf8 \
-quiet \
-boot-info-table \
-o os.iso \
iso

The ISO image os.iso now contains the kernel executable, the GRUB bootloader and the configuration file.

Step e: Running Bochs

Next we can run emulator using os.iso image file. Bochs needs a configuration file to start. Simple configuration file is given below.

bochsrc.txt

Copy above content and save it inside file called bochsrc.txt. Then locate it with the os.iso image file. Now the file should look like this.

Now execute following command in terminal and You will be able to see the emulator.

bochs -f bochsrc.txt -q

Now type continue in the terminal and then you will see some text inside the emulator. You can quit the emulator and display the log produced by Bochby executing following command:

cat bochslog.txt

If you find RAX=00000000CAFEBABE or EAX=CAFEBABE (depending on if you are running Bochs with or without 64 bit support) in the output then your OS has successfully booted!!!

After following above steps you will see the directory as follows.

Thank you for reading my article!!!

See you soon in next article!!!

--

--