Create My Little OS : MMP_OS 😊Week 02

Masith Pramuditha Jayarathna
4 min readOct 12, 2022

--

Let’s build our own Operating System — Week 02 🥳

Hi guys! we are back again. welcome to the second part of our article series. Here we are going to discuss about implementing the previously created (in week 01) Operating System in C. We discussed how to set up the development environment and boot a simplest OS. If you haven’t already read that article, I suggest you to do so because otherwise you won’t be able to understand this article.

Here is the link for the previous article:

Create My Little OS : MMP_OS 😊Week 01 | by Masith Pramuditha Jayarathna | Oct, 2022 | Medium

A little recap

Before we going to more details about today’s part. let’s rewind last week work. As mentioned previously we developed a little OS using Assemble language. The only thing that this OS do is putting a special number cafebabe to eax register. To accomplish this we use Ubuntu as our host operating system and Bochs as our virtual machine.

Getting to C

This article will demonstrate how to program the OS using C as opposed to assembly code. Assembly provides the most control over every component of the code and is excellent for communicating with the CPU. C, on the other hand, is a far more practical language to use, at least for the writers. As a result, we would prefer to utilize C wherever possible and assembly code only when necessary.

A stack is a need for utilizing C, as it is used by all non-trivial C programs. Making the esp register refer to the end of a free memory space (keep in mind that the stack grows towards lower addresses on the x86) that is perfectly aligned (alignment on 4 bytes is advised from a performance standpoint) is the most difficult part of setting up a stack.

We reserve a block of uninitialized memory in the bss section of the kernel’s elf file. Any memory set aside in the bss section will be allocated by GRUB since it is ELF-aware when the OS is loaded. Our method uses the NASM pseudo-instruction resb to declare uninitialized data.

Copy the following code to the file loader.s

The stack pointer is then set up by pointing esp to the end of the kernel_stack memory:

C function

Next thing that we have to is to call a C function from the assembly code. Since GCC uses the cdecl calling convention, we will use it here. According to the cdecl calling convention (on x86), arguments to a function should be provided through the stack.

The parameters for the function should be pushed into the stack from right to left, starting with the parameter on the right. The eax register holds the return value of the function.
The code following contains an example:

The assembly code which is used to call c function:

Compiling the C code

There are several flags for GCC that must be used when building the C code for the OS. This is because there is no standard library accessible for our operating system, therefore the C code shouldn’t presume its availability. We should also activate all warnings and handle them as errors.

To accomplish the aforementioned objectives when generating the C code, we use the following flags (we’ll use these in the Makefile we’ll construct in the next step):

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

Setup to Build Tool

Now we can set up some build tools to make compiling and testing our operating system easier. We suggest make, but there are a variety of different build systems to choose from. The following is an example of a basis Makefile for the OS:

Our working directory should now contain the following files in following order:

After all the modifications, the loader.s file will be like this

Since we configured the Makefile, we can start the OS with the simple command make run, which will compile the kernel and boot it in Bochs. Quit Bochs and display the log which is generated by Bochs with the cat bochslog.txt command. Then we can see number 6 in the eax register as bellow. That is because the function has returned number 6.

Here is my GitHub branch which contains this implementation.

MMPjayarathne/MMP_OS at implement_with_c (github.com)

Now are able to create our OS using the C language. We’ll examine how to obtain a console output the next week. Until then stay safe!

References:

Helin, E. and Renberg, A. (n.d.). The little book about OS development.

--

--