FAT32 Bootloader Problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: FAT32 Bootloader Problem

Post 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.
If you have seen bad English in my words, tell me what's wrong, please.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

Isn't it a problem when i have a 32bit cluster address in 16 bit real mode?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: FAT32 Bootloader Problem

Post by bluemoon »

you can do 32-bit arithmetic with 2 16-bit registers.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

But the dx register which stores the track/sector for the bios interrupt 13 is only 16bits?!?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: FAT32 Bootloader Problem

Post 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".
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post 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 :(
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

No idea? :(
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: FAT32 Bootloader Problem

Post by Combuster »

There's more output than carry to an int 0x13 call. Go check it.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: FAT32 Bootloader Problem

Post 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.
If you have seen bad English in my words, tell me what's wrong, please.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post 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?
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: FAT32 Bootloader Problem

Post 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.
If you have seen bad English in my words, tell me what's wrong, please.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

And how do i do it right? (Im sorry, i'be never used the extended read function so far)
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post 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?
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: FAT32 Bootloader Problem

Post by egos »

Use low dword.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: FAT32 Bootloader Problem

Post by Griwes »

Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
Post Reply