FAT32 Bootloader Problem
Re: FAT32 Bootloader Problem
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.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
Isn't it a problem when i have a 32bit cluster address in 16 bit real mode?
Re: FAT32 Bootloader Problem
you can do 32-bit arithmetic with 2 16-bit registers.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
But the dx register which stores the track/sector for the bios interrupt 13 is only 16bits?!?
Re: FAT32 Bootloader Problem
In that case you would need the BIOS extended function, AH=0x42 which take 64-bit (QWORD) LBA address in the "address packet".
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
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):
But it doesn't work, he prints "Failure" and throws the int 0x18
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
- Combuster
- 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
There's more output than carry to an int 0x13 call. Go check it.
Re: FAT32 Bootloader Problem
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
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.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
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
I have doubts that my advices will be heard. Well, I will try again.
DataStart = HiddenSectors + ReservedSectors + FATs*FATSize32
StartRootSector = DataStart + (SrartRootCluster-2)*SectorsPerClusterSo what is the start of the root dir?
DataStart = HiddenSectors + ReservedSectors + FATs*FATSize32
My smile tells that no.And is it right what i've done with the dunused and dsecatart in the dap?
If you have seen bad English in my words, tell me what's wrong, please.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
And how do i do it right? (Im sorry, i'be never used the extended read function so far)
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
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
Use low dword.
If you have seen bad English in my words, tell me what's wrong, please.
- Griwes
- 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
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
<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