有人知道如何为引导扇区获取exfat的根目录吗?我已经进行了许多小时的研究,但发现不起作用。尝试过的事情:根目录= 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
好吧,我走在正确的轨道上;但是,我的实现是不正确的。对于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。干杯!