View Full Version: What does a Boot loader do?

dex >>OS Dev >>What does a Boot loader do?


Pixelator- 06-04-2008
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.