So I had already made my bootloader in Fat12, and started to program in C.
But lately I wanted to switch to FAT32 so... I have set up the FAT32 Extended BIOS Parameter Block and everything else. But my question is in FAT12/16 you knew where the root directory was so it was easy to load into memory. But in FAT32 you don't. You can specify where it shold begin but how do I know how big it is to load it to memory?
Hope It's not too stupid but I can't figure it out, but I could in FAT12.
And also is the root directory entry the same as in FAT12.. I think i read it isn't!
Assembly bootloader FAT32
Re: Assembly bootloader FAT32
Bootloader - Read FATroban100 wrote:But my question is in FAT12/16 you knew where the root directory was so it was easy to load into memory. But in FAT32 you don't. You can specify where it shold begin but how do I know how big it is to load it to memory?
ClusterHi field was added. Read the Spec.And also is the root directory entry the same as in FAT12.. I think i read it isn't!
If you have seen bad English in my words, tell me what's wrong, please.
Re: Assembly bootloader FAT32
Unlike the fat12/16 RDEs, the Fat32 RDE is not a fixed size; it's a regular folder; it expands as needed. If you want to know how big it is you'll have to read through the cluster chain until you get an "End of File."roban100 wrote:how do I know how big it is to load it to memory?
I believe it starts at Cluster "2" (the first "real" cluster); I don't recall whether or not you can specify a different cluster (you said you already set up your extended BPB; if you can specify where the cluster the RDE starts at I'm sure it'd be there).
Re: Assembly bootloader FAT32
I wanted to do some paging tests in different environment so I wrote small stage2 for loading from FAT. It isn't really useful, but it can be a good start:
Code: Select all
mov ebx, dword [0x7DC6] ;0x7C00 + 0x1BE(first partition entry) + 8(LBA start on disk)
push ebx
%define FAT_BPB 0x9000 ;not only for BPB, but also for any temporary data
mov edi, FAT_BPB
mov si, 0x1 ;read BPB
call ata_pio28_read
;Getting some FAT info
xor eax, eax
mov ax, word [FAT_BPB+14]
mov word [rsvd], ax
add eax, dword [esp] ;Add reserved count to sector address
mov dword [fat_start], eax ;save address of FAT in memory for future use (when loading)
mov dword [esp], eax ;save address of FAT on stack
xor ecx, ecx
mov cl, byte [FAT_BPB+13]
mov byte [sec_p_c], cl
mov ax, word [FAT_BPB+11] ;bytes per sector
mov word [b_p_s], ax
mul cx
mov dword [b_p_c], eax
mov eax, dword [FAT_BPB+0x24]
mov dword [sec_per_fat], eax
xor ebx, ebx
mov bl, byte [FAT_BPB+0x10]
mov byte [n_of_fats], bl
mul ebx ;Multiply sectors per fat by # of fats to get their complete size
add dword [esp], eax ;Set sector pointer after FAT tables
pop dword [root_sec] ;save calculated fsroot
mov eax, dword [FAT_BPB+0x2C]
mov dword [actual_cluster], eax ;save for next loading
mov edi, FAT_BPB ;temporary data address
mov ebx, dword [actual_cluster]
.load_cluster:
call cluster_read
xor ecx, ecx
.search_cluster:
cmp byte [FAT_BPB+ecx], 0x0
jz .error
cmp byte [FAT_BPB+ecx], 0xE5
je .go
;test first 11 characters here (SFN)
.go:
add ecx, 0x20 ;32bytes for single directory entry
cmp ecx, dword [b_p_c]
jl .search_cluster
.not_found:
sub ebx, 2
cmp ebx, 0xFFFFFF0-2
jae .error
add ebx, 2
jmp .load_cluster
.error:
mov esi, kernel_not_found
call prints
jmp $
.found:
mov bx, word [FAT_BPB+ecx+20]
shl ebx, 16
mov bx, word [FAT_BPB+ecx+26]
mov edi, 0x200000
sub ebx, 2
.file_load:
add ebx, 2
call cluster_read
add edi, dword [b_p_c]
sub ebx, 2
cmp ebx, 0xFFFFFF0-2
jb .file_load
;mov edi, 0xb8000
;mov byte [es:edi], 'A'
;mov byte [es:edi+1], 0x0F
;add edi, 2
mov esi, kernel_found
call prints
mov esi, 0x200000
jmp $
;IN: EBX = cluster to read
;OUT: EBX = next cluster (by FAT table)
cluster_read:
xor ecx, ecx
mov cx, word [b_p_s]
shr cx, 2 ;4bytes per FAT entry
xor edx, edx
mov eax, ebx
div ecx
add eax, dword [fat_start]
push ebx
mov ebx, eax
mov si, 1
call ata_pio28_read
pop ebx
push dword [edi+edx*4] ;save next cluster from FAT table, pop on the end of function
xor eax, eax
mov al, byte [sec_p_c]
mov si, ax
sub ebx, 2
mul ebx
add eax, dword [root_sec]
mov ebx, eax
call ata_pio28_read
pop ebx
ret
sec_p_c: db 0 ;Sectors per Cluster
rsvd: dw 0 ;Reserved sectors count from the start of volume
sec_per_fat: dd 0 ;sectors per FAT table
n_of_fats: db 0 ;# of FAT tables
fat_start: dd 0 ;LBA of first FAT table
root_sec: dd 0 ;root sectors (calculated from FAT)
b_p_c: dd 0 ;bytes per cluster (sec_p_c * b_p_s)
b_p_s: dw 0 ;bytes per sector
actual_cluster: dd 0
kernel_not_found: db "Kernel not found!", 0
kernel_found: db "Kernel found!", 0
;EDI = read destination
;EBX = starting sector (LBA28)
;SI = # of sectors to read, value 0 means 256 sectors
ata_pio28_read:
...