Tuesday, July 07, 2009

Simple bootloader

Writing your own OS is something every computing person should do at some point. The first step is of course writing a boot loader. This is actually very easy to do under linux.

With a fresh install of ubuntu, make sure you have GCC and related goodies, the other things you will probably want are nasm, and virtual machine like QEMU. Installing these in ubuntu is as simple as:

sudo apt-get install nasm
sudo apt-get install qemu

(you may need to modify your /etc/apt/sources.list - any core ubuntu mirror will do, I used au.archive.ubuntu.com/ubuntu)

Now you probably want to try qemu out before going further, so grab freedos:
http://www.freedos.org/freedos/files/ and grab an iso, I got fdbasecd.iso

Now we create a virtual hard drive to install freedos on to: (do this in the same dir as the iso)

qemu-img create -f raw freedos.img 100M

And then we just boot up qemu:

qemu -localtime freedos.img -cdrom fdbasecd.iso -boot d

Freedos install is a bit obtuse, you need to format the drive to FAT16, exit the formatter, then again to FAT32, but I just pretty much just went with the defaults for everything, afterall, this is just for testing. At then end, you should have a working DOS prompt.

Now that we have QEMU working and we know it, let's try our own boot loader:

[BITS 16] ; 16 bit code generation
[ORG 0x7C00] ; ORGin location is 7C00

;Main program
main: ; Main program label

mov ah,0x0E ; This number is the number of the function in the BIOS to run.
; This function is put character on screen function
mov bh,0x00 ; Page number (I'm not 100% sure of this myself but it is best
; to leave it as zero for most of the work we will be doing)
mov bl,0x07 ; Text attribute (Controls the background and foreground colour
; and possibly some other options)
; 07 = White text, black background.
; (Feel free to play with this value as it shouldn't harm
; anything)
mov al,65 ; This should (in theory) put a ASCII value into al to be
; displayed. (This is not the normal way to do this)
int 0x10 ; Call the BIOS video interrupt.

jmp $ ; Put it into a coninuous loop to stop it running off into
; the memory running any junk it may find there.

; End matter
times 510-($-$$) db 0 ; Fill the rest of the sector with zeros
dw 0xAA55 ; Boot signature

Save the code to loader.asm, and assemble it with:

nasm loader.asm

Then, we can run our wonderful loader with:

qemu loader

No comments: