YmeOS — Let’s Build our own OS !!!😉

Thushara Samaraweera
3 min readJul 23, 2021

#2-Start implementing with C

Welcome back to the second stage of my Operating system article series. In my first article, I discussed how to build a simple operating system using ubuntu. If you seem lost I recommend going back to this article below

This article will give assistance to you in using the C programming language instead of assembly code as the programming language for the OS. Assembly is excellent for interacting with the CPU and provides complete control over all aspects of the code, but that’s not as convenient as the C programming language.

Creating a Stack

In order to jump into C language, we need to create a stack using assembly language. In our first implementation, We could point “esp to a random area in memory. But This is not a good idea because we don’t know how much memory is available or if the area “esp would point to is used by something else. In order to overcome that, It is better to use the “bss” section in the “loader.s” file to reduce the size of the OS executable. The below code will create a stack using assembly.

Reserving memory for the stack

Next, The stack pointer is then set up by pointing “espto the end of the “kernal_stack” memory. The below code will implement that part.

Setting up the stack pointer

In the next steps, We are going to call a C function from the assembly code. In order to do that we have to have a simple C program called “kmain.C” separate from others files. The function inside the C file would be like this and the return value of the function is placed in the “eax” register.

C function to add three integers

We will use the cdecl calling convention because it is the one used by GCC. According to the cdecl calling convention, arguments to functions should be passed through the stack. Consequently, the arguments should be pushed to the stack in right-to-left order, with the rightmost argument being pushed first. The function’s return value will be stored in the eax register.

To accomplish the task, place the following code after the esp instruction in the loader.s file

Calling C function from Assembly

After the above changes, The final “loader.s” file would be like this.

Makefile configuration

When compiling the C code, we use the following flags to achieve the aforementioned goals (We will use these in the Makefile which we are going to create in the next step):

-m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector 
-nostartfiles -nodefaultlibs -Wall -Wextra -Werror

Now is a good time to set up some build tools to make it easier to compile and test-run the operating system. A simple Makefile for the Operating system could look like the following code.

Now I am going to start the Operating system with the simple command “make run” which will compile the kernel and boot it up in Bochs as defined in the Makefile above.

Your final outcome would be like this.

Our working directory should now contain the following files:

References:

The Little OS Book: https://littleosbook.github.io/book.pdf

Thank you very much for reading!

Hope to see you again with the next chapter. Till then, STAY SAFE!!!

Happy reading …

-Thushara Samaraweera-

--

--