Page 2 of 3

Re: FAT32 Bootloader Problem

Posted: Wed Dec 05, 2012 9:05 am
by egos
FAT in FAT32 can be too large. I'm using 1 sector FAT cache. I'm reading root directory sector-by-sector until I have found required file records.

Re: FAT32 Bootloader Problem

Posted: Fri Dec 07, 2012 9:27 am
by tonydemann
Isn't it a problem when i have a 32bit cluster address in 16 bit real mode?

Re: FAT32 Bootloader Problem

Posted: Fri Dec 07, 2012 11:01 am
by bluemoon
you can do 32-bit arithmetic with 2 16-bit registers.

Re: FAT32 Bootloader Problem

Posted: Fri Dec 07, 2012 2:29 pm
by tonydemann
But the dx register which stores the track/sector for the bios interrupt 13 is only 16bits?!?

Re: FAT32 Bootloader Problem

Posted: Fri Dec 07, 2012 2:44 pm
by bluemoon
In that case you would need the BIOS extended function, AH=0x42 which take 64-bit (QWORD) LBA address in the "address packet".

Re: FAT32 Bootloader Problem

Posted: Mon Dec 10, 2012 4:47 am
by tonydemann
ok now i have the following code in order to load the starting cluster of the root dir into memory (i want to have a 1 cluster size cache for the root dir and one for the fat):

Code: Select all

BITS    16

ORG      0x7C00

Start:
   jmp      Skip
   nop
   
;*********************************************
;      OEM Parameter block, FAT 12/16/32
;      I dont use the values from this particular example
;      They are here for reference!
;*********************************************
bOemName      db      "MollenOS"      ;8 Bytes
;   /* FAT 12/16 BIOS Parameter Block starts here */
wBlockSize      dw      0
bSecPerClus      db      0
wReservedSecs   dw      0
bNumFats      db      0
wRootEntries   dw      0
wSectors16      dw      0
bMediaType      db      0
wFATSz16      dw      0
wSecPerTrack   dw      0
wNumHeads      dw      0
lSecCache      dd      0      ;lHiddenSecs
lSectors32      dd      0

;**********************************************
;      Extended BIOS Parameter Block
;**********************************************
lFATSz32      dd      0
wExtFlags      dw      0            ; Bits 0-3 = Active FAT, 7 = !FAT mirroring
wFSVer         dw      0
lRootCluster   dd      0
wFSInfo         dw      0
wBkBootSec      dw      0
BytesPerCluster   dd      0      ;Reserved1
CurrentCluster   dd      0      ;Reserved2
lDataSector      dd      0      ;Reserved3
bDriveNum      db      0
bReserved      db      0
bBootSig      db      0
lVolSerial      dd      0xDEADF007
szVolLabel      db      "MollenOS V1"
bSysID         db      "COPYHERE"


Skip:
	; -------------------- Adjust segment registers --------------------------------;
	cli
	xor ax, ax
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	
	; -------------------- Create Stack (0000 - FFFF) ------------------------------;
	mov ax, 0x0000
	mov ss, ax
	mov sp, 0xFFFF
	sti
	
	; -------------------- Display load message ------------------------------------;
	mov si, msgLoading
	call Print	
	
	; -------------------- Start loading KRNLDR.SYS --------------------------------;
	
	; Preparations
	mov ax, WORD[wBlockSize]						; calculate starting address of the fat cache, in order to put it directly after the rootdir cache
	mul WORD[bSecPerClus]							; size of a cluster = bytesPerSec * SecPerCluster
	mov WORD[wBytesPerCluster], ax					; store
	add ax, 0x0200									; first byte after the rootdir cache = 0x0200 (bootcode) + size of a cluster
	mov WORD[wFatCacheStart], ax					; move to the ram
	
	mov al, BYTE[bNumFats]
	mul DWORD[lFATSz32]
	add eax, DWORD[wReservedSecs]
	mov DWORD[dDataSector], eax
	
	mov ax, WORD[bSecPerClus]
	mov WORD[DAP.wSectorsToRead], ax					; tell the DAP to read 1 Cluster
	mov WORD[DAP.wSegment], ds							; store the actual Segment
	
	mov BYTE[bBootDrive], dl							; move starting-drive (in this case: usb stick) to the ram
	
	; --- STEP 1 (Root Dir Stuff) ---
	xor eax, eax
	mov eax, DWORD[lRootCluster]					; get the starting cluster of the root dir
	mul DWORD[bSecPerClus]							; multiply it by the number of Sectors per Cluster in order to get the absolute starting sector of the cluster
	mov DWORD[DAP.dSecStart], eax					; push it to the DAP
	xor ax, ax
	mov ax, WORD[wRootDirCacheStart]				; tell the DAP (BIOS INTERRUPT 13h) to store the cluster at 0x7C00:0x0200 (directyl above the bootcode)
	mov WORD[DAP.wOffset], ax
	call ReadCluster								; Read the cluster
	
	
	mov si, msgDone
	call Print
	
	
	;TODO
	
	; --------------------- End loading KRNLDR.SYS ----------------------------------;
	
	; --------------------- jump to KRNLDR.SYS --------------------------------------;
	
	;TODO
	
	cli
	hlt

Print:
	lodsb									; get next character
	or al, al								; check, if null-terminator
	jz PrintDone							; yes? -> printing done
	mov ah, 0eh								; no? -> print the character
	int 10h									; call BIOS
	jmp Print								; repeat until null-terminator found
PrintDone:
	ret										; printing done, so return
	
	
; ------ Read one Cluster to memory ----------- ;
; Input: DAP									;
; DAP.wSegment:DAP.wOffset = memory location		;
; DAP.dSecStart = starting sector of cluster	;
; --------------------------------------------- ;
ReadCluster:
	.MAIN
		mov di, 0x0005						; 5 times retry
	.CLUSTERLOOP
		mov ah, 42h							; Extended read sectors function
		mov si, DAP	
		mov dl, [bBootDrive]
		int 13h
		jnc .SUCCESS						; no error? -> cluster loaded successfully
		xor ax, ax							; error? -> reset disk
		int 13h
		dec di
		jnz .CLUSTERLOOP
		mov si, msgFailure					; still an error? -> Loading the Cluster failed, print "Failure" and halt the System
		call Print
		int 18h
		cli
		hlt
	.SUCCESS
		ret									; Successfully read the cluster, so return
	
	
; ------------------------ Variables ---------------------------------------------;
bBootDrive db 0
wFatCacheStart dw 0
wRootDirCacheStart dw 0x0200
wBytesPerCluster dw 0
dDataSector dd 0

dActualCluster dd 0

KRNLDR db "KRNLDR  SYS"

msgLoading db "Loading Boot Image...", 0x00
msgDone db "Done", 0x0D, 0x0A, 0x00
msgFailure db "Failure", 0x0D, 0x0A, 0x00

; ------------------------ Structs ------------------------------------------------;

DAP:						db 16,0 
	.wSectorsToRead:		dw 1                                ; Number of sectors to read (read size of OS) 
	.wOffset:				dw 0                                ; Offset
	.wSegment:				dw 0x7C00							; Segment (note: not segment:offset because of little endianes)
	.dUnused:				dd 0								; the absolute number of the starting sector is 64 bits, i only need 32, so this is unused
	.dSecStart:				dd 0


TIMES 510-($-$$) DB 0
DW 0xAA55
But it doesn't work, he prints "Failure" and throws the int 0x18 :(

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 6:12 am
by tonydemann
No idea? :(

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 6:18 am
by Combuster
There's more output than carry to an int 0x13 call. Go check it.

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 6:59 am
by egos

Code: Select all

.dUnused:
  dd 0 ; the absolute number of the starting sector is 64 bits, i only need 32, so this is unused
.dSecStart:
  dd 0
Heh, well done :)

Good reserve: 7E00h-7C200h

StartRootSector != StartRootCluster * SectorsPerCluster

And so on.

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 7:24 am
by tonydemann
So what is the start of the root dir? And is it right what i've done with the dunused and dsecatart in the dap?

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 8:11 am
by egos
I have doubts that my advices will be heard. Well, I will try again.
So what is the start of the root dir?
StartRootSector = DataStart + (SrartRootCluster-2)*SectorsPerCluster
DataStart = HiddenSectors + ReservedSectors + FATs*FATSize32
And is it right what i've done with the dunused and dsecatart in the dap?
My smile tells that no.

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 8:56 am
by tonydemann
And how do i do it right? (Im sorry, i'be never used the extended read function so far)

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 11:38 am
by tonydemann
I've checked the error code in ah and it is 01h, which means invalid command. Is it because of the wrong DAP?

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 1:12 pm
by egos
Use low dword.

Re: FAT32 Bootloader Problem

Posted: Tue Dec 11, 2012 1:32 pm
by Griwes