如何在程序集中获取exfat根目录?

问题描述 投票:0回答:1

有人知道如何为引导扇区获取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
assembly x86-16 bootloader osdev exfat
1个回答
0
投票

好吧,我走在正确的轨道上;但是,我的实现是不正确的。对于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。干杯!

© www.soinside.com 2019 - 2024. All rights reserved.