I've got a basic bootloader that should read the root sectors from a FAT12 formatted Floppy into the memory. (that part works) but after implementing that it stopped writing characters to the screen. Last time it did this was because I forgot to POP a register. But i've triple checked that I'm POPping every register back.
I've also used BOCHS Debugger and according to that it just reaches the end and executes the print character commands.
I'm stuck for now. I'd be really happy if anyone could take a look at my code.
This is my code:
org 0x7c00
bits 16
start: jmp loader
;OEM
TIMES 0Bh-$+start DB 0
bpbBytesPerSector: DW 512
bpbSectorsPerCluster: DB 1
bpbReservedSectors: DW 1
bpbNumberOfFATs: DB 2
bpbRootEntries: DW 224
bpbTotalSectors: DW 2880
bpbMedia: DB 0xF0
bpbSectorsPerFAT: DW 9
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder: DW 2
bpbHiddenSectors: DD 0
bpbTotalSectorsBig: DD 0
bsDriveNumber: DB 0
bsUnused: DB 0
bsExtBootSignature: DB 0x29
bsSerialNumber: DD 0xa0a1a2a3
bsVolumeLabel: DB "MOS FLOPPY "
bsFileSystem: DB "FAT12 "
;vars
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
;functions
print:
xor bx, bx
lodsb
cmp al, 00h
je print_eof
mov ah, 0eh
int 10h
jmp print
print_eof:
ret
;************************************************;
; Convert LBA to CHS
; AX=>LBA Address to convert
;
; absolute sector = (logical sector / sectors per track) + 1
; absolute head = (logical sector / sectors per track) MOD number of heads
; absolute track = logical sector / (sectors per track * number of heads)
;
;************************************************;
lbachs:
xor dx, dx ; prepare dx:ax for operation
div WORD [bpbSectorsPerTrack] ; calculate
inc dl ; adjust for sector 0
mov BYTE [absoluteSector], dl
xor dx, dx ; prepare dx:ax for operation
div WORD [bpbHeadsPerCylinder] ; calculate
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
ReadSectors:
push ax ;safety
push bx ;safety
push cx ;safety
call lbachs ;change LBA to CHS (floppy)
mov ah, 0x02 ;function to read sector from floppy
mov al, 0x01 ;read only 1 sector
mov ch, [absoluteTrack] ;at track X
mov cl, [absoluteSector];at sector X
mov dh, [absoluteHead] ;at had X
mov dl, 0x00 ;on drive 00 (floppydrive
int 0x13 ;execute
jnc .succes ;if succeeded goto succes else:
mov ah, 0x00 ;reset floppy drive
mov bl, 0x00 ;drive 0
int 0x13 ;execute
pop cx ;pop
pop bx
pop ax
jmp ReadSectors ;retry
.succes:
pop cx ;pop
pop bx
pop ax
add bx, WORD [bpbBytesPerSector] ;next 512 bytes in memory to write sector to
inc ax ;next sector
LOOP ReadSectors ;and keep looping till cx == 0
ret ;return
;Bootloader
loader:
mov si, msg
call print
xor cx, cx
mov ax, 0x0020 ; 32 byte directory entry
mul WORD [bpbRootEntries] ; number of root entrys
div WORD [bpbBytesPerSector] ; get sectors used by root directory
xchg cx, ax ;;cx=LENGTH in sectors
mov al, [bpbNumberOfFATs] ; Get number of FATs (Useually 2)
mul WORD [bpbSectorsPerFAT] ; number of FATs * sectors per FAT; get number of sectors
add ax, [bpbReservedSectors] ; add reserved sectors
;AX=START as sector in LBA (so needs conversion
mov bx, 0x0200 ; load root directory to 7c00:0x0200
call ReadSectors
mov cx, [bpbRootEntries] ; the number of entrys. If we reach 0, file doesnt exist
mov di, 0x0200 ; Root directory was loaded here
.LOOP:
push cx
mov cx, 11 ; eleven character name
mov si, imageName ; compare the 11 bytes with the name of our file
push di
rep cmpsb ; test for entry match
pop di
je LOAD_FAT ; they match, so begin loading FAT
pop cx
add di, 32 ; they dont match, so go to next entry (32 bytes)
loop .LOOP
jmp FAILURE ; no more entrys left, file doesnt exist :(
LOAD_FAT:
mov bh, 00h ;page to wwrite to.
mov ah, 0eh ;write character
mov al, 'Y' ;write the Y character
int 10h ;execute
jmp EoF ;jump to end of file
FAILURE:
mov bh, 00h ;page to write to
mov ah, 0eh ;write character
mov al, 'N' ;write the N character
int 10h ;execute
EoF:
mov bh, 00h ;see above :P
mov ah, 0eh
mov al, 'D'
int 10h
cli
hlt
streof db 'DONE....',0x0A, 0x0D, 00h
msg db 'Hello!', 0x0D, 0x0A, 00h
msg2 db 'Done reading root directory!', 0x0D, 0x0A, 00h
succ db 'YES file is found!', 00h
fil db 'Failed no file found!', 00h
imageName db "KRNLDR SYS"
times 510 - ($-$$) db 0
dw 0xAA55
Thanks in advance.
-Tim
PS: (for the ones going to say that I shouldn't copy code) I only copied the 'check if file exists' code from brokenthorn to see if I load the ROOT correct.
I fixed it.
After searching around and asking in irc I came to the conclusion that I did not set my Stack registers correctly. I changed
org 0x7c00
toorg 0
and after jumping to the loader (loader:
) I entered the stacks correctly like this:I hope this helps the ones that have the same problem!
-Tim