How to create your own OS?
Developing an operating system (OS) is not an easy task. I will put all implementation steps in series of articles it’s helps you easy to understand the steps and you can easily develop your very own OS.
Before starting you should know what is operating system?
An Operating System (OS) is a software that acts as an interface between computer hardware components and the user. Every computer system must have at least one operating system to run other programs. Applications like Browsers, MS Office, Notepad Games, etc., need some environment to run and perform its tasks.
so now you ready to develop your OS. I recommend you setup a virtual machine because in the implementation part some steps affect your local machine, so you follow the below steps:
I recommend VMware for virtual machine and ubuntu as OS (LTS).
Download links:
VMware: Download VMware Workstation Pro
Ubuntu: Get Ubuntu | Download | Ubuntu
This video helps you setup ubuntu on virtual machine,
No more the delay lets create our OS
#1- Load OS in Bootloader
1. Tools
1.1 Quick setup
Once Ubuntu is installed, either physical or virtual, the following packages should be installed using apt-get
:
sudo apt-get install build-essential nasm genisoimage bochs bochs-sdl
1.2 Programming Languages
The operating system will be developed using the C programming language, using GCC. We use C because developing an OS requires very precise control of the generated code and direct memory access.
The code will make use of one type attribute that is specific for GCC:
__attribute__((packed))
2. Booting
Booting an operating system consists of transferring control along a chain of small programs, each one more “powerful” than the previous one, where the operating system is the last “program”. See the following figure for an example of the boot process:
2.1 BIOS
Basic Input Output System (BIOS) stored on a read-only memory chip on the motherboard of the computer. The task of this program is to start the computer system after its power on. It will load some basic function instructions for hardware. And then it will transfer control to the bootloader.
2.2 Bootloader
This program will transfer control to us, the operating system. This program has two parts. The first part of will transfer control to the second part and that gives control of the PC to the operating system.
In this development process, we use an existing bootloader (GNU Grand Unified Bootloader-GRUB) because writing it from the beginning could complex. This GRUB will load OS into a correct memory location. Then the control will transfer to the Operating System.
2.3 The Operating System
GRUB will transfer control to the operating system by jumping to a position in memory. Before the jump, GRUB will look for a magic number to ensure that it is actually jumping to an OS and not some random code. This magic number is part of the multiboot specification which GRUB adheres to. Once GRUB has made the jump, the OS has full control of the computer.
3. Implement OS
This section will describe how to implement of the smallest possible OS that can be used together with GRUB. The only thing the OS will do is write 0xCAFEBABE
to the eax
register .
3.1 Compiling the Operating System
First create a folder as your OS name, Now open your favorite text editor, and paste the following code, and save it as loader.s
:
Now open terminal in the folder and run the below code,
The file loader.s
can be compiled into a 32 bits ELF object file with the following command:
nasm -f elf32 loader.s
3.2 Linking the Kernel
As we discussed before GRUB needs to load the kernel to the memory. For that, we need the following linking script. (That memory address should be larger than or equal to 1MB. Addresses lower than that will be used to GRUB, BIOS, and memory-mapped I/O.)
Save the linker script into a file called link.ld
. The executable can now be linked with the following command:
ld -T link.ld -melf_i386 loader.o -o kernel.elf
3.3 Obtaining GRUB
The GRUB version we will use is GRUB Legacy since the OS ISO image can then be generated on systems using both GRUB Legacy and GRUB 2. More specifically, the GRUB Legacy stage2_eltorito
bootloader will be used. This file can be built from GRUB 0.97 by downloading the source from:
windOS/stage2_eltorito at main · rragul/windOS (github.com)
Copy the file stage2_eltorito
to the folder that already contains loader.s
and link.ld
.
3.4 Building an ISO Image
We will create the kernel ISO image with the program genisoimage
. A folder must first be created that contains the files that will be on the ISO image. The following commands create the folder and copy the files to their correct places:(open your terminal in current folder 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
A configuration file menu.lst
for GRUB must be created. This file tells GRUB where the kernel is located and configures some options:(open your text editor and type the following code) in the title part you can put your OS name in my case i put as windOS so it be like
Place the file menu.lst
in the folder iso/boot/grub/
. The contents of the iso
folder should now look like the following figure:
iso
|-- boot
|-- grub
| |-- menu.lst
| |-- stage2_eltorito
|-- kernel.elf
The ISO image can then be generated with the following command:(open terminal and type following code)
genisoimage -R \
-b boot/grub/stage2_eltorito \
-no-emul-boot \
-boot-load-size 4 \
-A os \
-input-charset utf8 \
-quiet \
-boot-info-table \
-o windOS.iso \
iso
For more information about the flags used in the command, see the manual for genisoimage
.
The ISO image os.iso (your_title.iso)
now contains the kernel executable, the GRUB bootloader, and the configuration file.
3.5 Running Bochs
Now we can run the OS in the Bochs emulator using the os.iso
ISO image. Bochs needs a configuration file to start and an example of a simple configuration file is given below:
You might need to change the path to romimage
and vgaromimage
depending on how you installed Bochs. More information about the Bochs config file can be found at Boch’s website.
If you saved the configuration in a file named bochsrc.txt
then you can run Bochs with the following command:
bochs -f bochsrc.txt -q
if you using old ubuntu version you change the display_library: sdl2 to display_library: sdl.
Now you can see a window like this,
then Go to your terminal and type c like this,
now you can see your OS is successfully boot,
After quitting Bochs, display the log produced by Bochs:
cat bochslog.txt
If RAX=00000000CAFEBABE or EAX=CAFEBABE is in the output(bochs log file) then your OS has successfully booted!
Reference:
My Github repository for this: