What does a Boot loader do? Hi, i have written my own simple "Hello world" OS and im ready to start on the boot loader, but im not exactly sure how boot loaders work. I know that they switch control to the os, but i down't know how they do so. I have tried using "BootProg" but i cant get it to work.
I don't really need a complete boot loader strait out of thin air though, as i would like to learn how to make on of my own.
roboman- 06-04-2008
The whole boot strapping and boot loader thing goes back to one of the early conflicts in computer design. When computers were making the jump from entering programs with switches on a front panel or with jumper cables, one thought was to put the OS on a rom chip or on a cartridge, the other idea was to leave the system open and only put a very small program in rom that would load the OS from a storage device. Small hand held devices mostly have the OS on rom or flash and 'real' computers mostly load the OS from a storage device. Of course it gets a bit more complex. The bootstrap program on the PC can only load a very small program (about half a k or one k if you blow off disk info) Almost no OS is that small, so the bootstrap program on the PC loads a small program called a boot loader, from the storage device. The boot Loader then loads the OS. Some times it gets even more complex, the boot strap loads a boot manager that asks what OS you want to run and from what device and then the boot manager loads the boot loader, that loads the OS (lots of Linux systems are that way) So a boot loader or boot preogram is just a very small program that loads the OS and then does a jump to where ever in memory it loaded the OS to... The one Dex used is the least complex one I've seen and is also about the most flexable. Not that I've looked at all of them....
Dex- 06-05-2008
First if you keep your code less than 512bytes you will not need a bootloader, but as you code gets bigger you will need to load more than one sector.
So a simple bootloader's job is to be the first 512byte to load than, it needs to find the kernel or second stage bootloader (as more complecated bootloaders are much bigger than 512bytes) and load it into memory and jump to it.
Now to do this it useally users int 13h for reading from disk.
A good example is BOS
;------------------------------------------------------------;
; BOS - FAT12 bootsector ;
;------------------------------------------------------------;
; - FAT12 compatible. ;
; - Loads a binary file from the floppy, max ~576kb. ;
; - Sets A20 and protected mode. ;
; ;
; Thanks to: Petroff Heroj and John S. Fine for examples. ;
; ;
; by: Christoffer Bubach, 2003-2005 ;
; http://bubach.1go.dk/BOS/ bubach85@hotmail.com ;
; ;
;------------------------------------------------------------;
; other notes:
; this code is public domain, and you can use it for
; anything you want. but if you do, please act polite and
; give credit. ;-)
;
; mem map
; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff
; 0x0000:0x0500 -> 0x0000:0x2100 root
; 0x0000:0x2100 -> 0x0000:0x3300 fat
; 0x0000:0x3300 -> 0x0000:0x7c00 18,25kb free space
; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector
; 0x0000:0x7e00 <- 0x0000:0xffff 32,5kb stack
; 0x1000:0x0000 -> 0x9000:0xffff 576kb free space
; 0xa000:0x0000 -> ............. VGA mem etc.
use16
org 0x7C00
boot: jmp near start
nop
;------------------------------------------;
; Standard BIOS Parameter Block, "BPB". ;
;------------------------------------------;
bpbOEM db 'BOS 0.03'
bpbSectSize dw 512
bpbClustSize db 1
bpbReservedSec dw 1
bpbFats db 2
bpbRootSize dw 224
bpbTotalSect dw 2880
bpbMedia db 240
bpbFatSize dw 9
bpbTrackSect dw 18
bpbHeads dw 2
bpbHiddenSect dd 0
bpbLargeSect dd 0
;---------------------------------;
; extended BPB for FAT12/FAT16 ;
;---------------------------------;
bpbDriveNo db 0
bpbReserved db 0
bpbSignature db 0 ; 0 = nothing more. 41 = three more (below)..
; bpbID dd 1
; bpbVolumeLabel db 'BOOT FLOPPY'
; bpbFileSystem db 'FAT12 '
;----------------------------------------;
; starting point of bootsector code ;
;----------------------------------------;
start:
cli
xor ax, ax ; initialize all the necessary
mov ds, ax ; registers.
mov es, ax
mov ss, ax
mov sp, 0xFFFF ; Stack..
mov [bpbDriveNo], dl
sti
;----------------------------------;
; clear screen and print some ;
;----------------------------------;
mov ax, 3 ; Set mode 0x03
int 0x10
mov bp, loading ; Print loading message.
mov ax, 0x1301
mov bx, 7
mov cx, 12
mov dx, 0x0102
int 0x10
mov bl, 2 ; Set cursor.
mov ah, 2
mov dx, 0x0201
int 0x10
mov ah, 9 ; Print 14 green dots.
mov al, '.'
mov cx, 14
int 0x10
;---------------------------;
; load FAT and root ;
;---------------------------;
mov di, 0x0050 ; Load the root to
mov ax, 19 ; 0x0000:0x0500 (0x500/0x10)
mov cx, 14
call read_sectors
mov di, 0x0210 ; Load the fat to
mov ax, 1 ; 0x0000:0x2100
mov cx, 9
call read_sectors
;------------------------;
; search for the file ;
;------------------------;
mov dx, [bpbRootSize]
mov bx, 0x0500
filesearch:
cld
mov si, filename
mov cx, 11
mov di, bx
repe cmpsb
je found
add bx, 32
dec dx
jz error
jmp filesearch
;-----------------------------------;
; variables & functions ;
;-----------------------------------;
loading db 'Starting BOS'
filename db 'KERNEL SYS'
failure db 'Read error!'
a20_on db 1
;-----------------------------------------------;
; read a number of sectors (one at a time) ;
;-----------------------------------------------;
; in: ;
; di = segment to save at ;
; ax = sector to read ;
; cx = number of sectors ;
; out: ;
; di = updated (added for next read) ;
; ax = updated (added for next read) ;
;-----------------------------------------------;
read_sectors:
pusha
mov bl, byte [bpbTrackSect] ; bl = number of sectors per track
div bl ; al = ax / bl
mov cl, ah ; cl = real sector number
add cl, 1
xor ah, ah ; del the rest of the div before
mov bl, byte [bpbHeads] ; bl = number of heads
div bl ; ah = rest of ( ax / bx ), al = ax / bx
mov ch, al ; ch = number of track
mov dh, ah ; dh = the head number
mov ax, cx ; save cx in ax
mov cx, 6 ; try it 6 times
.next_try:
push es
push cx
mov cx, ax ; restore cx
push cx
xor ax, ax
mov dl, [bpbDriveNo] ; reset drive
push dx
int 0x13
jc .failed
pop dx
pop cx
xor bx, bx
mov es, di
mov ax, 0x0201 ; function 2, 1 sector
int 0x13
jnc .ok ; if it was ok, check next..
.failed:
pop dx
pop ax
pop cx
pop es
loop .next_try ; else try once again if there is an error
jmp error ; if cx = 0 and the read operation always failed, halt
.ok:
pop cx ; from the next_try loop
pop es
popa
add di, 32 ; add 32 (512/16) to segment
inc ax ; add sector counter
loop read_sectors
ret
;----------------------------------------------------;
; show a message and wait for a key before reboot ;
;----------------------------------------------------;
error:
;push 0x0000
;pop es
mov bp, failure
mov ax, 0x1301
mov bx, 4
mov cx, 43
mov dx, 0x0401
int 0x10
mov ah, 0
int 0x16
int 0x19
;-----------------------------------;
; the file is found, load it. ;
;-----------------------------------;
found:
mov bp, [bx+26] ; bp=cluster number from directory entry
mov di, 0x1000 ; 1000 (segment)
.next_block:
xor cx, cx
mov cl, [bpbClustSize] ; reset sector count to 1 cluster
mov si, bp ; si=next should-be cluster for
; contiguous reads
.next_contiguous:
mov ax, 3 ; 3
mul si ; multiply cluster number by 3
; dx assumed to be 0, it's a floppy!
shr ax, 1 ; divide by two
push bp
xchg bp, ax ; bp=ax
mov ax, word [0x2100+bp] ; ax=FAT element with junk
; (addressing with bp)
pop bp
jc byte .odd_cluster ; jump if the value was odd
.even_cluster:
and ax, 0x0FFF ; leave only lower 12 bits
jmp .got_cluster ; got it
.odd_cluster:
push cx ; preserve sector count
mov cl, 4 ; shift four bits right
shr ax, cl ; (leave only bits 4-15)
pop cx ; restore sector count
.got_cluster:
inc si ; si=current cluster+1
cmp ax, si ; next cluster=current cluster+1?
jne byte .force_read ; is it still contiguous?
add cl, [bpbClustSize] ; increase sector count by 1 cluster
adc ch, 0
jmp .next_contiguous
.force_read:
xchg bp, ax ; ax=bp (base cluster), bp=new cluster
dec ax ; decrease by 2 to get the actual... (1)
dec ax ; ...cluster number (2)
xor dx, dx
mov dl, [bpbClustSize]
mul dx ; multiply by sectors per cluster
; (dx ignored)
add ax, 33 ; assume data-area start at sector 33
call read_sectors ; read cx sectors at ax to es:0 :)
cmp bp, 0x0FF8 ; the new cluster is EOF (FF8-FFF)?
jb byte .next_block ; if not in this range, read next block
;-----------------------;
; the file is loaded ;
;-----------------------;
quit:
a20: ; Enable A20
in al, 0x64
test al, 2
jnz a20
mov al, 0xD1
out 0x64, al
.d6:
in al, 0x64
and ax, 2
jnz .d6
mov al, 0xDF
out 0x60, al
.a20_check:
mov al, byte [fs:0] ; check a20, is it on?
mov ah, al
not al
xchg al, byte [gs:0x10]
cmp ah, byte [fs:0]
mov [gs:0x10], al
jz floppy_off
mov [a20_on], 0 ; it's not on save for file..
floppy_off:
mov dx, 0x3F2 ; turn of the floppy motor.
mov al, 0
out dx, al
pmode:
cli ; set protected mode (32-bit)
lgdt [gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x08:flush
;----------------------------------------;
; start of 32-bit area. ;
; flush segments and jump to kernel ;
;----------------------------------------;
use32
flush:
mov eax, 0x10 ; refresh all segment registers
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0xfffc
mov eax, 0xB05B007 ; report "BOSboot".. ;-)
mov bl, [a20_on] ; report if a20 is on.
jmp 0x08:0x10000 ; jump to loaded file (64kb in mem)
;--------------------------------;
; global descriptor table (gdt) ;
;--------------------------------;
gdt: dw 0x0000, 0x0000, 0x0000, 0x0000
codesel: dw 0xFFFF, 0x0000, 0x9800, 0x00CF
datasel: dw 0xFFFF, 0x0000, 0x9200, 0x00CF
gdt_end:
gdtr: dw gdt_end - gdt - 1
dd gdt
;-------------------------------------;
; set the BOOT-signature at byte 510. ;
;-------------------------------------;
rb boot+512-2-$
dw 0xAA55
See here for full OS http://bos.asmhackers.net/
Pixelator- 06-05-2008
it needs to find the kernel or second stage bootloader (as more complecated bootloaders are much bigger than 512bytes) and load it into memory and jump to it.
where in memory, like in the hdd or in ram or where?
other that that it was much helpful.
Dex- 06-05-2008
The first 512bytes are load to physical address 0000:7C00 (Ram)
Here is some good info http://www.vnutz.com/content/program_a_bootstrap_loader
But be carefull as i think the code is nasm (the example i give are for fasm assembler)
Pixelator- 06-06-2008
TY VER VER MUCH!!!!!!!!!!!!
Unfourtunatly i can't work on my os because im at my grandparents house because my grandma is ver sick. When i get home i will start working right away.
Pixelator- 06-09-2008
ok im home
Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.