BUILDING YOUR OWN OS-part 1

Saman kumara
8 min readOct 2, 2022

--

What is an Operating System?

An operating system (OS) is a program that manages all other application programs on a computer after it is booted into the computer by a startup program. Application programs use the operating system by making requests for services through a defined application program interface. In addition, users can directly interact with the operating system through a user interface such as a command line interface (CLI) or a graphical user interface (GUI). A program that manages such programs is called an Operating System.

Laptops, tablets and desktop computers all run operating systems…

Examples include versions of Microsoft Windows (such as Windows 11, Windows 10, Windows 8, Windows 7, Windows Vista, and Windows XP), Apple’s macOS (formerly OS X), Chrome OS, and various Unix and Linux distributions. (Unix and Linux are open source operating systems.).A smartphone runs a mobile operating system. They are mainly use on Android and IOS.

Tools we need to develop OS

01) Host Operating System

Mostly coders use UBUNTU as a host operating system for OS development. Ubuntu is the modern, open source operating system on Linux for the enterprise server, desktop, cloud, and IoT. It running both physically and virtually. By installing the OS on a virtual machine like VirtualBox we can test our OS easily.

02)Packages

After installing Ubuntu physically or virtually, the following package should be installed by using apt-get. We should type the below mentioned command in the terminal.

03)Programming Languages

The operating system is developed using C programming language. We use C because developing an OS requires very precise control of the code we develop and very good access to memory. Other languages that provide the same features can also be used for this.

04)Virtual Machine

When developing an operating system it is very convenient to be able to run our code on a virtual machine instead of a physical computer. That’s because booting our OS in a virtual machine is much faster than running it on a physical medium. Using a virtual machine can’t guarantee that our OS will run on real physical hardware and can be copied to an executable CD. The operating system can be tested in one by finding a suitable machine.

Booting

Booting an operating system consists of transferring control along a chain of small programs. Booting is the process of starting a computer. It can be initiated by hardware, such as pressing a button, or by a software command. A CPU does not have software in its main memory after it is turned on, so some processes must load software into memory before they can be executed. This can be done by the CPU’s hardware or firmware
or by a separate processor in the computer system.

See the following figure for an example of the boot process:

BIOS(Basic Input / Output System)

BIOS is a computer program used by the CPU to perform initialization procedures when the computer is turned on, in the entire Basic Input and Output system. Its two main steps are determining which peripheral devices such that keyboards, mouse, disk drives, printers, video cards, etc. — are available, and loading the operating system into main memory. This is software stored on a small memory chip permanently on then motherboard and is the first software that runs after a computer starts up. It manages the data flow between the computer’s operating system (OS) and attached devices.

Bootloader

Loading an operating system’s data into working memory is an essential task at device startup. This can be done by a boot program or a so-called bootloader called a bootstrap loader. For this purpose, when a device starts up, a bootloader is usually launched from a bootable medium such as a hard disk, CD/DVD, or USB stick. Bootable media receives information from the computer’s firmware (eg : BIOS) about where the bootloader resides. This entire process is also described as “initiation”.

When you press the start button on a computer, the first thing you see on the screen is information about the installed hardware. The software causing this notification is the device firmware mentioned above. Usually implemented by manufacturers of flash memory on the computer’s motherboard. With most desktop computers and notebooks this is the BIOS or the more modern UEFI (Unified Extensible Firmware Interface).

When this process is complete, the firmware moves through the found data carriers in sequence. The search always starts on removable media (CD/DVD, USB stick, external hard drive, etc.). After that hard-coded drivers. With the latter, the bootloader and its signature are usually in the Master Boot Record (MBR). It also contains partition tables of the data carrier. When a bootloader is found, it is loaded and system startup begins. If the search fails, the firmware will return an error message.

The Operating System

when GRUB jumps to a location in memory then control is transferred to the operating system.to jump, GRUB looks for a magic number to ensure that it is actually jumping to an OS and not random code. Once GRUB is booted, the OS has full control of the computer.

Writing and Compiling

This OS part should be written in assembly code and C requires a stack. The only thing is OS will do is write a very specific number 0xCAFEBABE to the eax register.

global loader ; the entry symbol for ELF
MAGIC_NUMBER equ 0x1BADB002 ; define the magic number constant
FLAGS equ 0x0 ; multiboot flags
CHECKSUM equ -MAGIC_NUMBER ; calculate the checksum
; (magic number + checksum + flags should equal 0)
section .text: ; start of the text (code) section
align 4 ; the code must be 4 byte aligned
dd MAGIC_NUMBER ; write the magic number to the machine code,
dd FLAGS ; the flags,
dd CHECKSUM ; and the checksum
loader: ; the loader label (defined as entry point in linker script)
mov eax, 0xCAFEBABE ; place the number 0xCAFEBABE in the register eax
.loop:
jmp .loop ; loop forever

By using the following command to compile loader.s into a 32-bit ELF object file.

nasm -f elf32 loader.s

Linking

We must link the code to produce an executable file, which requires some extra thought when linking multiple programs. It uses less than 1 MB of addresses because GRUB itself, BIOS, and memory-mapped I/O. GRUB loads from a memory address greater than or equal to 1 MB as we want. So, we are not able to use the following script as the link.

ENTRY(loader) /* the name of the entry label */
SECTIONS {
. = 0x00100000; /* the code should be loaded at 1 MB */
.text ALIGN (0x1000) : /* align at 4 KB */
{
*(.text) /* all text sections from all files */
}
.rodata ALIGN (0x1000) : /* align at 4 KB */
{
*(.rodata*) /* all read-only data sections from all files */
}
.data ALIGN (0x1000) : /* align at 4 KB */
{
*(.data) /* all data sections from all files */
}
.bss ALIGN (0x1000) : /* align at 4 KB */
{
*(COMMON) /* all COMMON sections from all files */
*(.bss) /* all bss sections from all files */
}
}

Let’s save this script as a file named ‘link.id’. to link the executable type the following command. Then we can see a file named ‘kernel.elf’ as final executable.

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

Obtaining GRUB

The GRUB version we use in GRUB Legacy, since the OS ISO image can then be generated on systems using both GRUB Legacy and GRUB 2. The GRUB Legacy stage2_eltorito bootloader will be used.copy the file stage2_eltorito to the folder that consist loader.s and link.ld

Building an ISO Image

The executable should be stored on a virtual or physical machine readable medium and for that we will use the ISO image files of our project. We can use genisoimage program to create the image.

Create a folder containing the files from the ISO image and use the following commands to create the folder and copy the files to their correct location:

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

Then we should make a GRUB configuration file named ‘menu.lst’. This file should instruct GRUB where to find the kernel and set various options.
Use the following configuration for the file:

default=0
timeout=0
title os
kernel /boot/kernel.elf

Then place the ‘menu.lst’ file in the folder ‘iso/boot/grub/’. Now the ‘iso’ folder should contain the following structure:

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

After that use the following command to create the iso file.

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

A file named ‘os.iso’ includes an executable kernel. Instead of executing the kernel, the iso image contains the GRUB bootloader and configuration file.

Running the OS with Bochs

Using the os.iso ISO image, we can now boot our OS in the Bochs emulator. To get started with Bochs, we need a configuration file. Following is a simple configuration file.

megs: 32
display_library: sdl
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
ata0-master: type=cdrom, path=os.iso, status=inserted
boot: cdrom
log: bochslog.txt
clock: sync=realtime, time0=local
cpu: count=1, ips=1000000

Depending on how we install Bochs we may need to adjust the path to roimage and vgaromimage.

Save the configuration file as ‘bochsrc.txt’ and run Bochs with the following command:

bochs -f bochsrc.txt -q

Bochs simulated the contents of the CPU’s registers, which could appear anywhere in the output. Similarly, if the output shows RAX=00000000CAFEBABE or EAX=CAFEBABE, we can conclude that our OS has started successfully.

Next, we just created a simple operating system. In next week we shall see how to develop our OS by using C programming.

References……..

  1. https://pasandevin.medium.com/build-your-own-os-117ad262dee5
  2. The Little OS Book: https://littleosbook.github.io/book.pdf

3. https://www.javatpoint.com/booting-in-operating-system

4. http://duartes.org/gustavo/blog/post/how-computers-boot-up

5. http://duartes.org/gustavo/blog/post/kernel-boot-process

6. http://wiki.osdev.org/Boot_Sequence

Thank you very much for reading hope you got good knowledge. Let’s see next chapter in next week.

—Saman Kumara —

--

--