как получить корневой каталог exfat в сборке?
Кто-нибудь знает, как получить корневой каталог exfat для загрузочного сектора? Я провел много часов исследований, и то, что я обнаружил, не работает. Вещи пробовали: Rootdirectory = RootCluster * SectorsPerCluster + ReservedSectors; Первый сектор FAT + ReservedSectors + RootCluster. Любое множество их комбинаций. Проблема в том, что если я получаю правильное значение для корневого каталога, я пробую его на диске другого размера (отформатированный exfat) и не получаю правильный корневой каталог. Любая помощь / код будут оценены! Спасибо
информация: NASM X86 exFat
USE16
org 0x7C00
%define FileSystem bp+3 ; 8
%define MustBeZero bp+11 ; 53
%define HiddenSectors bp+64 ; 8
%define TotalSectors bp+72 ; 8
%define FatFirstSector bp+80 ; 4
%define FatTotalSectors bp+84 ; 4
%define ReservedSectors bp+88 ; 4
%define TotalClusters bp+92 ; 4
%define RootCluster bp+96 ; 4
%define SerialNumber bp+100 ; 4
%define Version bp+104 ; 2
%define VolumeFlags bp+106 ; 2
%define BytesPerSectorShift bp+108 ; 1
%define SectorsPerClusterShift bp+109 ; 1
%define NumberOfFats bp+110 ; 1
%define PhysicalDrive bp+111 ; 1
%define PercentInUse bp+112 ; 1
%define Reserved bp+113 ; 7
%define BootCode bp+120 ; 390
%define BootSignature bp+510 ; 2
%define ExcessSpace bp+512 ; 2
times 120 db 0
Start:
mov [bsDriveNumber], dl ; BIOS passes drive number in DL
xor eax, eax
xor esi, esi
xor edi, edi
mov ds, ax
mov es, ax
mov bp, 0x7c00
; Make sure the screen is set to 80x25 color text mode
mov ax, 0x0003 ; Set to normal (80x25 text) video mode
int 0x10
mov si, msg_Load
call print_string_16
xor ebx, ebx
xor ecx, ecx
mov eax, 1 ; cluster shift start
mov cl, [SectorsPerClusterShift] ; get actual cluster shift
dec cl ; -1 (eax has the first shift)
rol eax, cl ; convert shift to sectors
mov ebx, [RootCluster] ; get start of root cluster
mul ebx ; Clusters Per Shift * Root Cluster
add eax, [ReservedSectors] ; + Reserved Sectors = Root Directory ??
call printEAX
mov bx, 0x8000 ; address to put root directory
mov si, bx
mov di, bx
call readsector ; eax = sector #
mov bx,0x8000 ; if we dont get a value of 3,
mov eax, [bx] ; we didnt load the right root sector for Root Directory
call printEAX ; NOTE: Root sector for this disk is 408
mov ax, 0
int 016h
int 019h
; 16-bit Function to print a sting to the screen
; input: SI - Address of start of string
print_string_16: ; Output string in SI to screen
pusha
mov ah, 0x0E ; int 0x10 teletype function
.repeat:
lodsb ; Get char from string
cmp al, 0
je .done ; If char is zero, end of string
int 0x10 ; Otherwise, print it
jmp short .repeat
.done:
popa
ret
;------------------------------------------------------------------------------
; Read a sector from a disk, using LBA
; input: EAX - 32-bit DOS sector number
; ES:BX - destination buffer
; output: ES:BX points one byte after the last byte read
; EAX - next sector
readsector:
push dx
push si
push di
read_it:
push eax ; Save the sector number
mov di, sp ; remember parameter block end
push byte 0 ; other half of the 32 bits at [C]
push byte 0 ; [C] sector number high 32bit
push eax ; [8] sector number low 32bit
push es ; [6] buffer segment
push bx ; [4] buffer offset
push byte 1 ; [2] 1 sector (word)
push byte 16 ; [0] size of parameter block (word)
mov si, sp
mov dl, [bsDriveNumber]
mov ah, 42h ; EXTENDED READ
int 0x13 ; http://hdebruijn.soo.dto.tudelft.nl/newpage/interupt/out-0700.htm#0651
mov sp, di ; remove parameter block from stack
pop eax ; Restore the sector number
jnc read_ok ; jump if no error
push ax
xor ah, ah ; else, reset and retry
int 0x13
pop ax
jmp read_it
read_ok:
inc eax ; next sector
add bx, 512 ; Add bytes per sector
jnc no_incr_es ; if overflow...
incr_es:
mov dx, es
add dh, 0x10 ; ...add 1000h to ES
mov es, dx
no_incr_es:
pop di
pop si
pop dx
ret
printEAX:
push eax
call dumpEAX
mov al, ' '
call os_output_char
pop eax
ret
dumpEAX:
ror eax, 24
call dumpAL
rol eax, 8
call dumpAL
rol eax, 16
dumpAX:
ror eax, 8
call dumpAL
rol eax, 8
dumpAL:
push ebx
push eax
mov ebx, hextable
push eax
shr al, 4
xlatb
call os_output_char
pop eax
and al, 0x0F
xlatb
call os_output_char
pop eax
pop ebx
ret
os_output_char:
push eax
mov ah,0x0E
int 0x10
pop eax
ret
bsDriveNumber db 0
msg_Load db "Mios", 0
hextable db '0123456789ABCDEF'
times 510-$+$$ db 0
sign dw 0xAA55
1 ответ
Что ж, я был на правильном пути; однако моя реализация была неправильной. Для загрузочного сектора exFat правильная формула выглядит следующим образом:
mov eax, 1 ; cluster shift start
mov cl, [SectorsPerClusterShift] ; get actual cluster shift
rol eax, cl ; convert shift to sectors
mov ebx, [RootCluster] ; get start of root cluster
dec ebx ; subtract 2
dec ebx
mul ebx ; Clusters Per Shift * Root Cluster
add eax, [ReservedSectors] ; + Reserved Sectors
add eax, [FatFirstSector] ; + FAT table = Root Directory start
Это то, что я обнаружил, что дает мне правильный корневой каталог для дисков exFat разного размера. Примечание: это основано на обычном формате. Количество FAT = 1. Ура!