Wednesday, March 31, 2010

Make your own OS

Requirements:
- Emu8086 (
8086 Microprocessor Emulator with Integrated 8086 Assembler)
- Rawwrite (RawWrite)
- Some knowledge about 16-bit x86 assembler (If you don't have got this, look for a tutorial)
- An empty
floppy disk(optional but recommended)


Part I: the boot sector

When you
start emu8086 choose a new BOOT template.
Ok, this is the base for
the boot sector of a drive, there are 2 essential things in it, "#make_boot#" tells it is meant as boot sector.
"org 7c00h" is for telling it its loading address has to be 0000:7c00.
Let's make it say hello world or something, without the dos interrupt, so we've got to make an own procedure to
write a string.
There is a bios
function to write a single char(The teletype function: ah = 0eh/int 10h) so we use that:

; You need to put a null byte at the end of your string
; Before calling this procedure you have to make si the offset of your string.
printstring proc near
nextchar:
mov al, [si] ; Copy the first char to al
cmp al, 0 ; Comparing al with 0
jz printed ; If it is null, jump
to the end
inc si ; Move to the next char
mov ah, 0eh ; The teletype function.
int 10h ; Put the char
jmp nextchar ; Repeat it...
printed:
ret
printstring endp

And some function for http://www.bdpplz.com/vforum/images/smilies/waiting.gifuntil a key is pressed:

mov ax, 0
int 16h

The key pressed will be returned in al.

For rebooting the pc you need this, unfortunately I don't understand this piece, but is makes your os reboot the pc.
mov ax, 0040h
mov ds, ax
mov w.[0072h], 0000h ; I know this piece says to do a cold boot. To make it do a warm boot, replace 0000h with 1234h.

JMP 0FFFFh:0000h ; Yes, reboot!

Well, now you can combine that!
Let it print some text like hello world and wait until a key is pressed and then reboot!
The easiest way to test is emulating.

Part II: The kernel

Well, now you know how to make the boot sector but the boot sector can only be up to 512 bytes, that's why you need a kernel.
We make a little kernel to put at sector 2, but you will need to make the boot sector loading it:

mov ah, 02h ; The read function
mov al, 5 ; Number of sectors to read, it is set to 5, if your kernel grows larger than this, change it
mov ch, 0 ; The cylinder number
mov cl, 2 ; The sector where it starts reading
mov dh, 0 ; The head number
; Set es to the address to load the kernel to
mov bx, 0800h
mov es, bx
mov bx, 0
; Read the kernel
int 13h
; Check if the kernel is loaded
cmp es:[0000],0E9h ; Comparing the first byte of kernel, it should be 0E9 which means jmp
jmp 0800h:0000h ; If the kernel is loaded, jump to it

This loads the kernel and checks if the kernel is loaded successfully by checking the first byte, usually you put something at the begin like:
jmp start
; A list of variables
start:
So the first byte is always jmp, whose hex value is 0E9...


Ok, let's make the kernel!
Start start emu8086 a second time and choose a new BIN template.
The first thing to put in it is "ORG 0000h" to say it starts at that address, afther that, there has to be the command jmp (to somewhere) so the boot sector will recognise it.
An inportant piece for making the kernel running fine is this:
push cs
pop ds
I don't know why it is required, but you get problems with variables if you haven't inserted it.
Now you can just put code there as if it is the boot piece.

When you've finished the kernel, compile it and run the emulator for the booting part.
First choose "virtual drive > write 512 bytes at 0000:7c00 to boot sector > FLOPPY_0"
Then, "virtual drive > write '.bin' to floppy...", choose the kernel file you've just compiled, set the sector to 2 and write.
If you want to run it in the emulator choose "virtual drive > boot from virtual floppy > FLOPPY_0", click run and have fun!
If you want to make a bootable disk, run rawwrite, choose the file FLOPPY_0 in the installation directory of emu8086 and have fun!

No comments:

Post a Comment

Welcome to my site
powered by Mypagerankcheck