Build up my OS (Wathsala’s OS) — Part 01
An operating system (OS) is the program that, after being initially loaded into the computer by a boot program, manages all of the other application programs in a computer.
A beginners guide to Operating System — Part 1
Building an OS is somewhat difficult and complex. Today we are going to develop a little OS which is called as Wathsala’s OS.
Tools and Technologies…
- Ubuntu serves as the host operating system for our computer. Installing the host operating system in a virtual machine like VirtualBox is an excellent idea while testing the OS.
2. Once Ubuntu is installed, either physical or virtual, the following packages should be installed using the terminal.
sudo apt-get install build-essential nasm genisoimage bochs bochs-sdl
3. Programming Languages — We will use the C Programming language with GCC compiler to develop our OS. We chose C because constructing an operating system necessitates precise control over the generated code as well as direct memory access.
4. Virtual Machine — When creating an operating system it is much easier to be able to run code in a virtual environment than on a physical computer. That’s because booting from a virtual machine is significantly faster than running your OS on a physical disk. We will use Bochs Emulator as our virtual machine.
Booting
In order to create an operating system, it is essential to understand how it boots up. This chapter will guide you through the OS booting process.
The process of booting an operating system involves transferring control through a series of small programs, each one more powerful than the one before it. The main programs in this process include BIOS, Bootloader, and the OS. The operating system is the final and the most powerful one.
BIOS
The PC will launch a program that follows the Basic Input Output System (BIOS) standard as soon as it is turned on. BIOS mostly performs some initial diagnostics (power-on-self-test) before handing off the command to the bootloader. The program’s original purpose was to export some library features for screen printing, keyboard input reading, etc.
Writing and Compiling
Assembly language must be used to construct this OS component. Since the C language requires a stack, which is not there, we are unable to utilize it.
Save the following code in a file titled “loader.s”.
Once we run our OS we can check whether the code writes the number 0xCAFEBABE to the EAX register.
After creating the loader.s then use the following command to compile loader.s into a 32-bit ELF object file.
nasm -f elf32 loader.s
After entering this command in the terminal, we can see ‘loader.o’ file has been created in the working directory.
Linking
After the code has been compiled, it must be linked to create an executable file. Because addresses less than 1 megabyte (MB) are used by GRUB, BIOS, and memory-mapped I/O, we want GRUB to load the kernel at a memory address greater than or equal to 0x00100000 (1 MB). We can use the following script as the linker.
Create a file called ‘link.ld’ with the link script. Using the following command, you can now link the executable:
ld -T link.ld -melf_i386 loader.o -o kernel.elf
Obtaining GRUB
More specifically, the GRUB Legacy stage2_eltorito bootloader will be used. After downloading the binary file copy the file stage2_eltorito to the folder that already contains loader.s and link.ld.
creation of the ISO image
The executable needs to be kept on a physical or virtual machine-readable medium. In our project, we will use ISO image files for that. To make the image, we can utilize the genisoimage application.
The files that will be on the ISO image should be placed in a folder. To create the folder and copy the files to their correct locations, use the following commands:
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 create a GRUB configuration file called ‘menu.lst’. This file should instruct GRUB to find the kernel and set various options. Use the following configuration for the file:-
default=0timeout=0title oskernel /boot/kernel.elf
Place the ‘menu.lst’ file in the folder ‘iso/boot/grub/’. Then 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 called ‘os.iso’ will be generated. This contains the kernel executable, the GRUB bootloader, and the configuration file.
Running our OS with Bochs
Using the os.iso ISO image, we can now boot our OS in the Bochs emulator. To get started with Bochs, you’ll need a configuration file. Following is a simple configuration file.
Depending on how you installed Bochs, you may need to adjust the path to romimage and vgaromimage. You can refer to Boch’s official website to find out more about Bochs configuration. Save the configuration file as ‘bochsrc.txt’ and run Bochs with the following command:
bochs -f bochsrc.txt -q
Bochs should now be running and presenting a console with some information on it. Quit Bochs and display the log generated by Bochs with the command below:
cat bochslog.txt