Implementing SachOS With C

Sachithra_Manamperi
4 min readJul 23, 2021

This is the second part of the Operating System Implementation series. If you haven’t already done so, I recommend reading my first article on setting up the development environment and starting the operating system.

I’m following Erik Helin and Adam Renberg’s guidance “The little book about OS development” for the coding and implementation employees.

We used assembly language instead of C in the previous article. Assembly is ideal for dealing with the CPU because it gives you complete control over every component of the program. We prefer C since it is a lot more convenient language to work with.

Creating a Stack

Making the “esp” register point to the end of a correctly aligned block of free memory is all it takes to set up a stack. To decrease the size of the OS executable, utilize the “bss” part rather than the “data” section. Because GRUB understands ELF, any memory reserved in the “bss” section will be allocated when the OS is loaded.

To do so, we must copy this part of code into the “loader.s” file.

KERNEL_STACK_SIZE equ 4096                  ; size of stack in bytes

section .bss
align 4 ; align at 4 bytes
kernel_stack: ; label points to beginning of memory
resb KERNEL_STACK_SIZE ; reserve stack for the kernel

By directing “esp” to the end of the “kernel stack” memory, the stack pointer is created. To set up the stack pointer, add the following code

mov esp, kernel_stack + KERNEL_STACK_SIZE   ; point esp to the start of the
; stack (end of memory area)

After that, your loader.s file should now look like the one below.

Using Assembly to Call C Code

The next step is to use the assembly code to call a C function. This function’s return value is stored in the “eax” register. The function is shown in the following code, which should be saved as “kmain.c.”

int sum_of_three(int arg1, int arg2, int arg3) {  

return arg1 + arg2 + arg3;
}

It’s not enough to write a C function. We’ll have to use assembly to call it.
Arguments to functions should be provided through the stack, according to the cdecl calling convention.

To accomplish this, add the following code to the loader label of the loader.s file after the esp instruction.

; The assembly code
external sum_of_three ; the function sum_of_three is defined elsewhere

push dword 3 ; arg3
push dword 2 ; arg2
push dword 1 ; arg1
call sum_of_three ; call the function, the result will be in eax

Build Tools

It’s also a good time to open up some build tools to make compiling and testing the OS easier. We recommend “make,” although there are a variety of other build systems to choose from.
To specify how to create the kernel and boot up the OS, we need to store this code as a “Makefile.”

OBJECTS = loader.o kmain.o
CC = gcc
CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector \
-nostartfiles -nodefaultlibs -Wall -Wextra -Werror -c
LDFLAGS = -T link.ld -melf_i386
AS = nasm
ASFLAGS = -f elf

all: kernel.elf

kernel.elf: $(OBJECTS)
ld $(LDFLAGS) $(OBJECTS) -o kernel.elf

os.iso: kernel.elf
cp kernel.elf iso/boot/kernel.elf
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

run: os.iso
bochs -f bochsrc.txt -q

%.o: %.c
$(CC) $(CFLAGS) $< -o $@

%.o: %.s
$(AS) $(ASFLAGS) $< -o $@

clean:
rm -rf *.o kernel.elf os.iso

Then, using the “make run” command, you may compile the kernel and boot up the OS in Bochs. Now you can see how to boot up your OS on Bochs.

After Running the make run command

Remember, If you get a message like “Bochs not responding,” type “continue” in the terminal where Bochs is executing.

The contents of your working directory should now appear as shown in the diagram:

.
|-- bochsrc.txt
|-- iso
| |-- boot
| |-- grub
| |-- menu.lst
| |-- stage2_eltorito
|-- kmain.c
|-- loader.s
|-- Makefile

If you did it correctly, you should see “EAX=00000006” in the freshly created “bochslog.txt” logfile. Here’s a quick command Using piping to locate that text

cat bochslog.txt | grep EAX
After Running The command the output should be like this

It was a pleasure to write to you and I will be back next week with part 3.

Click Here to Find the Source Code

https://github.com/SachPrecious/SachOS

--

--

Sachithra_Manamperi

Undergraduate | Software Engineering | Dharmaraja College Kandy | Sri Lankan