This series of articles can be used as a supplement to teaching operating system courses and exercises to help to understand the working of operating systems better.

This OS development series is a step-by-step tutorial designed and developed to supplement teaching the subject by faculty. My main objective is to provide hands-on experience to students undergoing operating system courses. These tutorial series do not need hardcore programming skills. 

Designing an operating system is a hard task. It requires in-depth knowledge of computer hardware, interrupts, real mode, protected mode, computer architecture, and organization. Teaching the course with practicality while using Linux, Minix and other source code is a tough deal.

As these are serious pieces of work and to make the students understand, in 3 months is a herculean task. So I intended to develop something which is simple and needs basic programming skills. If one is interested then he/she may read further and enhance the code or involve in other OS development projects. 

To start with, readers are advised to follow the steps given in the tutorial. We will be using Ubuntu operating system any version. I used Ubuntu 20.04 for the entire tutorial. For Windows and Mac users

Virtualbox with Ubuntu might be a choice.


  • Basic understanding of a computer.
  • Basic understanding of Assembly language 80×86, assembling code using nasm, as86,ld86.
  • Basic understanding of C programming language.

Hardware/Software requirements

  • A working PC/Laptop.
  • Bochs: A cross-platform IA-32 emulator or Virtualbox.
  • An editor: Vim, nano, or gedit (for linux).
  • Operating System Ubuntu 12.04 or Windows with Virtualbox.
  • gcc compiler
  • Netwide Assembler: nasm
  • Hexdump: The hexdump utility is a filter that displays the specified files, or the standard input, if no files are specified, in a user-specified format.
  • A standard low-level copying utility for Linux operating system: dd.

Our entire operating system series can be summarized as follows

Phase -I

Planning our operating system design and capabilities. Planning the development is a critical step. As we must know our objectives and milestones that we would like to achieve. For designing our system we will stick to the most basic functionalities of an operating system:-

  • A system that boots a computer system.
  • To restrict actual LOC(Lines of Code) to be minimal.
  • Design as a CUI(Character User Interface).
  • Works as a uni-programming system.
  • A command-line interpreter as in Linux and DOS operating systems.
  • A monolithic kernel(Reference – 5).

Phase -II


In this section, we will cover bootloader design and development, which will boot your system.

This section will cover the following points:-

  • Booting process
  • Assembling of the code(Reference -3).
  • Copying of the code to a virtual floppy disk.
  • Booting the system.

To set up a development environment

This section will explain to you the setup of the development environment for your own operating system. Windows users can install Virtualbox and then install Ubuntu on it. To do this first open up the terminal by pressing ALT+CTRL+T. After you have done this follow the below-mentioned steps:

  1. Type at a command prompt. $ sudo apt-get update
  2. After the system has updated its repositories. Type the command to install build essential.$ sudo apt-get install build-essential
  3. Now install bcc (This is a C-compiler for 8086 CPUs which is important for the development of boot loaders or BIOS related 8086 code). $ sudo apt-get install bcc nasm

Now, the system is ready to roll your own bootloader.

A bootloader is a program that sets the prerequisites for the kernel to load and perform the functionalities. When the system is powered on BIOS reads the sector 0 of the disk and then loads the bootloader code in memory at 0x00007C00. The size of a bootloader has to be 512 bytes so that it fits in the range 0x00007C00 – 0x00007DFF and ends with 0x55 0xAA(Reference-1).

This minimal bootloader will be used to:

  • Boot the system.
  • Print a string on the screen.

Operating System Code:

To start with our bootloader, type the following code in the text editor and save it with filename bootloader.asm

;This is a boot loader program that hangs after printing Welcome Message

;Run bochs using the following command :==> bochs -q ‘boot:a’ ‘floppya:1_44=floppy.img, status=inserted’ [BITS 16]

; Tells the assembler that it’s a 16-bit code 

[ORG 0x7C00] ; Origin, tells the assembler where the code will be in memory after it is loaded 
MOV SI, WelcomeString ;Store string pointer to SI

CALL _PrintString ;Call print string procedure

JMP $ ;Infinite loop, hang it here.

_PrintCharacter: ; Procedure to print a character on screen

;Assume that ASCII value is in register AL

MOV AH, 0x0E ;Tells BIOS that we need to print one character on screen.

MOV BH, 0x00 ;Page no.

MOV BL, 0x07 ;Text attribute 0x07 is light grey font on black background

INT 0x10 ;Call video interrupt

RET ;Return to calling procedure

_PrintString: ;Procedure to print string on screen

;Assume that string starting pointer is in register SI

next_character: ;Label to fetch next character from string

MOV AL, [SI] ;Gets a byte from string and store in AL register

INC SI ;Increment SI pointer

OR AL, AL ;Checks if value in AL is zero (end of string)

JZ exit_function ;If end then return

CALL _PrintCharacter ;Else print the character which is in AL register

JMP next_character ;Fetch next character from string

exit_function: ;End label

RET ;Return from procedure


WelcomeString db ‘Welcome to Toy OS….’, 0

TIMES 510 – ($ – $$) db 0 ;Fill the rest of sector with 0

DW 0xAA55 ;Add boot signature at the end of bootloader

To assemble the code follow the instructions:

  1. You will need to assemble the bootloader.asm with nasm(Reference -4). $ nasm bootloader.asm
  2. After it assembles it will create a binary file. Type the command “ls” on the command prompt to see the created binary file.
  3. Next step is to copy the binary file in a virtual floppy disk. $ dd if=bootloader of=floppy.img bs=512
  4. After creating the virtual floppy as floppy.img. Open virtualbox and create a machine.
  5. After creating the virtual machine. Right click on the virtual machine you created and select settings.
  6. Click on storage. Then click on floppy controller from the icons.
  7. Now click on choose disk button to add the floppy image, you created.
  8. You have now added the floppy disk to the system. You can now start the machine to see you minimal bootloader.

You can test the work without writing the code. Download the file from below. Open Virtualbox and attach the image to Virtualbox floppy to test it. If you are still not able to do then check out the video below.

Testing ToyOS

This is a complete minimal bootloader that boots the system and prints a string on the screen. Our next article will be focused on phase – III which is system calls.


Editor: Gaurav Parashar