Disk Operating System/Your First Bootloader
Your First BootloaderEdit
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.
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
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.)
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.