Implementing Own Operating System(OS) with C (Part 2)
This article is the second part of implementing your own OS. You can go through the below link to get an idea of my previous article.
In this part, we are going to think about how we implement our own OS using C. In the first article, we looked at how to implement the OS with assembly languages. Although it provides efficient CPU interaction. However, the C language is more convenient than assembly. Also, it has some different and features when doing implementation with C.
Let’s move to the steps!!!
Step 01 Setting Up a Stack
It is a must for utilizing C because a stack is used in every non-trivial C program. We must direct it esp
to the end of a properly aligned free memory space in order to create 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 because it is ELF-aware when the OS is loaded. Our method uses the NASM pseudo-instruction resb
to declare uninitialized data.
We have to add the below code in the loader.s
file.
After that, set the stack pointer by pointing esp
to the end of the kernel_stack
memory. Below code helps to change the loader section in the loader.s
file.
Step 02 Calling C Code From Assembly
First C function
This C program is the first program. In this example, it is going to return three integer sums.
Although, as a next step, we have to create a new file called kmain.c
to save the below codes.
Call C function using assembly
There are many methods to call C function using assembly. Here we are going to see how we call C functions through Assembly with cdecl
calling convention. because it used by GCC. According to the cdecl
calling convention, arguments should be provided to a function through the stack (on x86). The function’s arguments should be added to the stack from right to left, starting with the argument on the right. The eax
register receives the function’s return value.
The below code shows the assembly language to call the C function. This code should be copied into the loader.s
file.
If you do the instructions or steps correctly, then you can see the loader.s
file like below:
Step 03 Compiling C Code
To compile C code on the OS, there are some flags that are required to be used by GCC. Therefore, the below flags have to be added in our instruction. Although these flags will be include in new file called Makefile
(Next step you can see it)
-m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector
-nostartfiles -nodefaultlibs-Wall -Wextra -Werror
Step 04 Build Tools
This is the final file we have to create to build this setup successfully. This file will be created by the name of Makefile
. Use of copying all the below instructions, we can get the complete code for Makefile
file.
Once we successfully accomplish file making and changing, we can get a complete set up of this part 2 process. Which is implementing own OS using with C.
Likewise, the contents of your working directory should now look like the following figure:
Using the make run
command, we can start our OS setup using C as below.
Furthermore, if you require any clarification, use my Git URL to clarify.
I hope this article will be useful for implementing an OS with C.
Be happy and keep learning!
Thank you.