Jump to content

Disk Operating System/Your First Bootloader

From Wikiversity

Objective

[edit | edit source]
  • Learn a little about the computer's booting process.
  • Learn how to create a simple bootloader.
  • Learn how to boot the bootloader.

Your First Bootloader

[edit | edit source]

Short Introduction

[edit | edit source]

Hello and welcome to the first hands on lesson in this course! Please refer to the Introduction page for tools and supplies you may need. You should note that, for quickness and its ability to take screenshots, I'll be using an emulator instead of running my operating system on a physical disk.

Bootloader

[edit | edit source]

When a computer boots up, each disk drive is scanned for a special boot sector signature at the end of the boot sector. The boot sector signature is the last two bytes at the end of the boot sector (starting at offset 0x1FE). If a disk drive has this signature, then the computer loads the boot sector at position 0x7C00. The boot sector is only 512 bytes in size, so we'll need to fill our bootloader with some empty padding up until the boot sector signature. So let's setup a little demonstration.

	; This hangs the computer.
	cli
	hlt

Now, let's add the offset mentioned earlier. To do this, we'll have to use origin.

	org 0x7C00

	; This hangs the computer.
	cli
	hlt

This could isn't bootable yet, since we don't have the boot sector signature. To set this up, we'll need to put some padding of zero's all the way up until offset 0x1FE (decimal 510). Instead of manually writing zero's into our code, we can use a Nasm trick. Another great thing about this trick is that it will warn you if your code runs past the boot sector signature's offset.

	org 0x7C00

	; This hangs the computer.
	cli
	hlt

	; Fills our bootloader with zero padding.
	times 510-($-$$) db 0

Now that we have a way to put our boot sector signature at the end of the file. That special signature is 0x55 and 0xAA.

	org 0x7C00

	; This hangs the computer.
	cli
	hlt

	; Fills our bootloader with zero padding.
	times 510-($-$$) db 0

	; This is our boot sector signature, without it,
	; the BIOS will not load our bootloader into memory.
	db 0x55
	db 0xAA

Since the boot sector signature is two bytes in size, we could replace it with a word.

	org 0x7C00

	; This hangs the computer.
	cli
	hlt

	; Fills our bootloader with zero padding.
	times 510-($-$$) db 0

	; This is our boot sector signature, without it,
	; the BIOS will not load our bootloader into memory.
	dw 0xAA55

Notice how the signature seems to have changed. It hasn't, since the x86 architecture is little endian. This may seem a little confusing at first, but you'll get more comfortable with the idea later on.

Now we can assembly (not compile!) our small bootloader. I'll give an example below using the file name bootloader.asm.

nasm bootloader.asm -f bin -o bootloader.bin

Now you can put it onto a virtual or physical disk. If don't have the tools or have no idea how to do that, I wrote up this little Python script that allows you to add a bootloader to a virtual floppy disk (this Python script creates a virtual floppy disk if it doesn't exist.)

bootloader.py - A simple Python script that puts a bootloader onto a virtual floppy disk.
#!/usr/bin/env python

# The above comment is actually a Unix Shebang for cross-platform compatibility.

"""
    Written by I8086 @ http://en.wikiversity.org/wiki/User:I8086
    for the Wikiveristy course,
    Disk Operating System @ http://en.wikiversity.org/wiki/Disk_Operating_System/

    Copyright (c) 2014 I8086.
    Version 1.0

    You are free to do what ever you want with Python script, so long as retain
    the information and copyright notice. No warranty is given and come's "AS IS".
    The copyright holder(s) isn't responsible for any bugs in the Python script.
    Use at your own risk.
"""

# Import the os library.
import os

# Set the title of our program.
os.system("title bootloader.py")

# Get the name of the bootloader.
bootloader = input("Bootloader: ")

# If the bootloader exists, then read
# it. If it doesn't exist, then display
# and error and exit.
if (os.path.exists(bootloader)):
    file = open(bootloader, "br")
    boot = file.read()
    file.close()
else:
    print("This file doesn't exist!")
    os.system("pause")
    exit(1)

# Get the name of the virtual floppy disk.
outfloppy = input("Virtual Floppy Disk: ")

# If it exists, then add the bootloader at
# the boot sector. If it doesn't exist, then
# Create a new virtual floppy disk and the
# bootloader.
if os.path.exists(outfloppy):
    file = open(outfloppy, "br+")
    file.write(boot)
    file.close()
else:
    file = open(outfloppy, "bw")
    file.write(boot)
    file.write(b'\x00'*1474048)
    file.close()



If you don't have Python, I recommend that you get it, since most of the course's custom tools while be written in Python for cross-platform compatibility and for fast development. If not, you're welcomed to use your own or others tools.

Now that we have a way to put the bootloader onto the virtual drive (in our case, we'll use a virtual floppy disk, until said otherwise) we can run this in our emulator of choice or on a real computer. When you run your small bootloader, your computer or emulator should hang. Congratulations! You have successfully ran your first operating system. Feel free to play around with your bootloader and customize it.

Assignments

[edit | edit source]
  • Create a simple bootloader that hangs the computer. (Hint: The Source code to do so is with in the lesson.)
  • Build your simple bootloader with Nasm (or your assembler of choice).
  • Boot your simple bootloader on an emulator or from a real computer.

Completion status: Ready for testing by learners and teachers. Please begin!