Page 1 of 1

FAT again

Posted: Fri Sep 01, 2006 4:24 pm
by killedbydeath
Hi all,
I'm trying to write my own fat bootsector. For now i want it to load the root dir to a memory segment and check for a file called test.txt if it's there it shall display a "File Found!!!!" Message and hang and if it doesn't a "File not foun" and hang. But instead it only displays a blinking cursor so i don't know if has done it's job or not :'(. Here is my code

Code: Select all

[BITS 16]
[ORG 0]
jmp short start
nop
OEM_ID db 'MANYLOLS'
BytesPerSector dw 0x0200
SectorsPerCluster db 0x01 
ReservedSectors dw 0x0001
TotalFats db 0x02
MaxRootEntries dw 0x0E0
TotalSectors dw 0x0B40
MediaDescriptor db 0xF0
SectorsPerFat dw 0x0009
SectorsPerTrack dw 0x0012
NumHeads dw 0x0002
HiddenSectors dd 0x00000000 
TotalSectorsLarge dd 0x00000000
DriveNumber db 0x00
Flags db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "Testdisk   "
SystemID db 'FAT12   '

start:
mov ax,0x7C0
mov ds,ax
mov es,ax
mov ax,0x0000
mov ss,ax
mov sp,0xFFFF

; load file kernel.bin to 1000:0000
success db 'FileFound!!!!',0
filenotfound db 'FilenotFound',0
rootdirsec db 0
firstrootsec db 0 
ABSsector db 0
ABStrack db 0
ABShead db 0
filename db 'TEST    TXT' 
main:
xor ax,ax
xor dx,dx
mov dl,[DriveNumber]
int 13h
call findroot
call getroot
push es
call searchroot



findroot:     ;Let's Find the root directory ;)
xor ax,ax
mov ax,[MaxRootEntries] ; Rootdirsectors=((Maxrootent*32)+(BytesPerSec-1))/BPS
mov bx,32
mul bx
xor bx,bx
mov bx,[BytesPerSector]
dec bx
add ax,bx
div BYTE [BytesPerSector]
mov di,rootdirsec
mov [es:di],ax
firstdatasec:  ; find first data sector
xor ax,ax
mov ax,[ReservedSectors]
mov bx,[TotalFats]
add ax,bx
mov bx,12
mul bx
add ax,[rootdirsec]
mov di,firstrootsec
mov [es:di],ax

getroot:
xor cx,cx
xor bx,bx
mov cx,[rootdirsec] ; COUNT IN CX 
mov bx,[firstrootsec] ; LBA IN BX 
loopsec:
cmp cx,0
je finished
call LBACHS
call readsector
inc bx
dec cx
jmp loopsec
finished:
ret

LBACHS:
xor dx,dx
xor ax,ax
mov ax,bx
div BYTE [SectorsPerTrack] ;Sector
inc dx
mov di,ABSsector
mov [es:di],dx
xor ax,ax
xor dx,dx
mov ax,bx
div BYTE [SectorsPerTrack]
div BYTE [NumHeads]
mov di,ABStrack
mov [es:di],dx
mov di,ABShead
mov [es:di],ax
ret

readsector:
push es
push bx
push cx
xor ax,ax
xor bx,bx
xor dx,dx
xor cx,cx
mov ah,0x2
mov al,0x1
mov ch,[ABStrack]
mov cl,[ABSsector]
mov dh,[ABShead]
mov dl,[DriveNumber]
mov ax,9A00h
mov es,ax
int 13h
pop cx
pop bx
pop es
ret

searchroot:
mov ax,9A00h
mov es,ax
mov cx,11
xor di,di
push di
mov si,filename
repe cmpsb
pop di
je filefound ; ;D
add di,32
mov ax,di
mov dl,32
div dl
cmp ax,[MaxRootEntries]
jle searchroot
jmp failure ; :(

filefound:
mov ax,0x7C0
mov es,ax
mov si,success
call print
jmp hang
failure:
mov si,filenotfound
call print
jmp hang
print:
lodsb
cmp al,0
je printend
mov ah,0Eh
mov bh,0h
mov bl, 0Fh
int 10h
jmp print

printend:
ret
hang:
jmp hang

times 510-($-$$) db 0
dw 0AA55h
That's my first bootsector all my info is from fatgen103.pdf i need help and suggestions

Re:FAT again

Posted: Fri Sep 01, 2006 6:36 pm
by Ryu
killedbydeath wrote: jmp short start
nop
.....

start:
mov ax,0x7C0
mov ds,ax
mov es,ax
mov ax,0x0000
mov ss,ax
mov sp,0xFFFF
;<---- *execution continues into data ----->
;<---- add a jmp short main here to fix ---->
; load file kernel.bin to 1000:0000
success db 'FileFound!!!!',0
filenotfound db 'FilenotFound',0
rootdirsec db 0
firstrootsec db 0
ABSsector db 0
ABStrack db 0
ABShead db 0
filename db 'TEST TXT'
main:
xor ax,ax
xor dx,dx
mov dl,[DriveNumber]
int 13h
call findroot
call getroot
push es
call searchroot
....
This is the most obvious, declare the data before the start label or put it somewhere that will not go in the program flow like making a jump to main label.

Re:FAT again

Posted: Sat Sep 02, 2006 2:12 am
by Pype.Clicker
i think the best i can suggest you is to make yourself friend with BOCHS's debugger. Set a breakpoint at 0x7c00, let BIOS initialization flow, and then execute your code step by step, asking for cpu_dump when you want to check registers values ...

Re:FAT again

Posted: Sat Sep 02, 2006 8:33 am
by killedbydeath
apart from the segment problems are my fat12 calculations for getting the root dir correct?

Best Regards

Re:FAT again

Posted: Sat Sep 02, 2006 11:39 am
by killedbydeath
i discovered that i had not put a ret in findroot ;D but it didn't solve the problem :'( :'( I also tried to track down the problem using bochs debugger with no success

Re:FAT again

Posted: Sat Sep 02, 2006 12:42 pm
by killedbydeath
I also added in main to print a string "My FAT12 bootsector" and it prints it so the problem is in the other functions :-\

Re:FAT again

Posted: Sat Sep 02, 2006 1:15 pm
by Combuster
right now you seem to be attempting to find the root directory at LBA:sectors in root dir - which would be sector 14
However the root directory comes immediately after the FAT, that is [number of fats] * [fatsize] + [reserved sectors], which iirc is commonly 2 * 9 + 1 = 19, cylinder 0, head 1, sector 2.

When debugging, try to double check register contents with what it _should_ be. That'd most assuredly help you to the conclusion that your chosen sector is incorrectly calculated. In the first run i'd notice sector 14 be accessed which can't possibly be correct.

Debugging is an art and practice makes perfect. 8)

Re:FAT again

Posted: Sun Sep 03, 2006 10:23 am
by killedbydeath
Well i managed to solve some of the problems using bochs' debug but now it seems i have some problems with the floppy reading
here's my new code

Code: Select all

[BITS 16]
[ORG 0]
jmp short start
nop
OEM_ID db 'MANYLOLS'
BytesPerSector dw 0x0200
SectorsPerCluster db 0x01 
ReservedSectors dw 0x0001
TotalFats db 0x02
MaxRootEntries dw 0x0E0
TotalSectors dw 0x0B40
MediaDescriptor db 0xF0
SectorsPerFat dw 0x0009
SectorsPerTrack dw 0x0012
NumHeads dw 0x0002
HiddenSectors dd 0x00000000 
TotalSectorsLarge dd 0x00000000
DriveNumber db 0x00
Flags db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "Testdisk   "
SystemID db 'FAT12   '

start:
mov ax,0x7C0
mov ds,ax
mov es,ax
mov ax,0x0000
mov ss,ax
mov sp,0xFFFF
jmp short main
welcome db 'My FAT12 Booting',0
; load file kernel.bin to 1000:0000
success db 'FileFound!!!!',0
filenotfound db 'FilenotFound',0
rootdirsec db 0
firstrootsec db 0 
ABSsector db 0
ABStrack db 0
ABShead db 0
;Debug
pointa db 'First Breakpoint',0
pointb db 'Second Breakpoint',0
pointc db 'Third Breakpoint',0

filename db 'TEST    TXT' 
main:
mov si,welcome
call print 
xor ax,ax
xor dx,dx
mov dl,[DriveNumber]
int 13h
call findroot
call getroot
push es
call searchroot



findroot:
mov ax,0E0Ah;D                 
int  10h;D
mov si,pointa; for debug
call print ; for debug     
;Let's Find the root directory ;)
xor ax,ax
mov ax,[MaxRootEntries] ; Rootdirsectors=((Maxrootent*32)+(BytesPerSec-1))/BPS
mov bx,32
mul bx
xor bx,bx
mov bx,[BytesPerSector]
add ax,bx
div WORD [BytesPerSector]
;mov di,rootdirsec
mov [rootdirsec],ax
jmp firstdatasec
firstdatasec:  ; find first data sector
xor ax,ax
mov ax,[TotalFats]
mov bx,[SectorsPerFat]
mul bx
mov bx,[ReservedSectors]
add ax,bx
;mov di,firstrootsec
mov [firstrootsec],ax
mov ax,0E0Ah                 
int  10h
mov si,pointb ;for debug 
call print ; for debug
ret
getroot:
mov ax,0E0Ah ;for debug                 
int  10h ;D 
mov si,pointc ;for debug
call print
xor cx,cx
xor bx,bx
mov cx,[rootdirsec] ; COUNT IN CX 
mov ax,[firstrootsec] ; LBA IN AX 
loopsec:
cmp cx,0
je finished
call LBACHS
xor ax,ax
mov ax,0x0200 ; Load root to 0x7c00:0200
mov bx,ax
call readsector
inc ax
dec cx
jmp loopsec
finished:
mov ax,0E0Ah ;D                  
int  10h ;D 
mov si,pointc ;D
ret

LBACHS:
xor dx,dx
div WORD [SectorsPerTrack]
inc dl
mov [ABSsector],dl
xor dx,dx
div WORD [NumHeads]
mov [ABShead],dl
mov [ABStrack],al
ret
readsector:
push cx

xor ax,ax
xor dx,dx
xor cx,cx
mov ah,0x2
mov al,0x1
mov ch,[ABStrack]
mov cl,[ABSsector]
mov dh,[ABShead]
mov dl,[DriveNumber]
int 13h
pop cx
ret

searchroot:
mov ax,9A00h
mov es,ax
mov cx,11
xor di,di
push di
mov si,filename
repe cmpsb
pop di
je filefound ; ;D
add di,32
mov ax,di
mov dl,32
div dl
cmp ax,[MaxRootEntries]
jle searchroot
jmp failure ; :(

filefound:
mov ax,0x7C0
mov es,ax
mov si,success
call print
jmp hang
failure:
mov si,filenotfound
call print
jmp hang
print:
lodsb
cmp al,0
je printend
mov ah,0Eh
mov bh,0h
mov bl, 0Fh
int 10h
jmp print

printend:
ret
hang:
jmp hang

times 510-($-$$) db 0
dw 0AA55h
and here's bochs' output
bochs' output comes in next post

Re:FAT again

Posted: Sun Sep 03, 2006 10:25 am
by killedbydeath

Code: Select all

00000000000i[MEM0 ] allocated memory at 0x40431008. after alignment, vector=0x40432000
00000000000i[MEM0 ] 1,00MB
00000000000i[MEM0 ] rom at 0xf0000/65536 ('/usr/share/bochs/BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/32768 ('/usr/share/vgabios/vgabios.cirrus.bin')
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Sun Sep  3 18:55:21 2006 (time0=1157298921)
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[FDD  ] fd0: '/home/philip/fd.img' ro=0, h=2,t=80,spt=18
00000000000i[MEM0 ] Register memory access handlers: 000a0000-000bffff
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24
00000000000i[VGA  ] interval=40000
00000000000i[     ] init_mem of 'harddrv' plugin device by virtual method
00000000000i[     ] init_mem of 'keyboard' plugin device by virtual method
00000000000i[     ] init_mem of 'serial' plugin device by virtual method
00000000000i[     ] init_mem of 'parallel' plugin device by virtual method
00000000000i[     ] init_mem of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_mem of 'speaker' plugin device by virtual method
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] Using boot sequence floppy, none, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'speaker' plugin device by virtual method
00000000000i[SPEAK] Failed to open /dev/console: Ξ?Ο?ΞΉΟ?Ο?Ο?Ξ―Ξ?
00000000000i[SPEAK] Deactivating beep on console
00000000000i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'speaker' plugin device by virtual method
00000000000i[XGUI ] [x] Mouse off
00000000000i[     ] Warning: no rc file specified.
00000000000i[     ] set SIGINT handler to bx_debug_ctrlc_handler
Next at t=0
(0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b         ; ea5be000f0
<bochs:1> c
00000004176i[BIOS ]  rombios.c,v 1.121 2004/10/15 15:34:44 vruppert Exp $
00000080000e[VGA  ] character height = 1, skipping text update
00000160000e[VGA  ] character height = 1, skipping text update
00000240000e[VGA  ] character height = 1, skipping text update
00000318567i[KBD  ] reset-disable command received
00000320000e[VGA  ] character height = 1, skipping text update
00000400000e[VGA  ] character height = 1, skipping text update
00000421247i[VBIOS] VGABios $Id: vgabios.c,v 1.59 2004/07/18 20:22:43 vruppert Exp $
00000480000i[XGUI ] charmap update. Font Height is 16
00000560000i[XGUI ] charmap update. Font Height is 16
00000877014i[FDD  ] read() on floppy image returns 0
00000900942i[FDD  ] read() on floppy image returns 0
00000924867i[FDD  ] read() on floppy image returns 0
00000948792i[FDD  ] read() on floppy image returns 0
00000972717i[FDD  ] read() on floppy image returns 0
there are thousands "read() on floppy image returns 0" but i shortened it
Any ideas about what it is and how to solve it?
Thank you for your time

Re:FAT again

Posted: Mon Sep 04, 2006 2:51 am
by Pype.Clicker
grepping bochs source for the error message pointed out the following part of "floppy.cc":

Code: Select all

grep "read() on floppy image returns 0" * -r
iodev/floppy.cc:

Code: Select all

    if (ret < int(bytes)) {
      /* ??? */
      if (ret > 0) {
        BX_INFO(("partial read() on floppy image returns %u/%u",
          (unsigned) ret, (unsigned) bytes));
        memset(buffer + ret, 0, bytes - ret);
        }
      else {
        BX_INFO(("read() on floppy image returns 0"));
        memset(buffer, 0, bytes);
        }
      }
    }
so i'd say that means you're reading past the size of the image, and that the emulator therefore consider there should be zeroes there.

oh, and btw, it's going to become very tedious to read you if you post +4 screens of ASM code every time you modify a RET... there's an option to attach source files, so unless you need to show us a precise excerpt of your code, just attach the file, don't dump it, okay?