flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Error in fatgen103 
Author 

Mike Gonta 28 Mar 2011, 01:41
There is an error in the FAT Volume Initialization algorithm (on page 21) to calculate the number of sectors in a FAT32
File Allocation Table. Even though the document is over 10 years old it's still the most current. fatgen103, page 21 wrote: Do not spend too much time trying to figure out why this math works. The basis for the computation is complicated; Then add two clusters to account for the first two FAT entries. The total data sectors of the volume must be less or equal to 4GB1 for FAT32 and the MBR table. These sectors are not managed by the FAT. This leaves the total data sectors, divide by the sectors per cluster for the total data clusters. Divide the total data clusters by the sector size divided by 4 to get the total FAT sectors. Any fractional remainder will require one extra FAT sector. Code: FATSz = DskSize  BPB_ResvdSecCnt  (2 * FATSz) + (2 * BPB_SecPerClus)/ BPB_SecPerClus * (BPB_BytsPerSec / 4) Code: FATSz * (BPB_SecPerClus * (BPB_BytsPerSec / 4)) = DskSize  BPB_ResvdSecCnt  (2 * FATSz) + (2 * BPB_SecPerClus) Code: (FATSz * (BPB_SecPerClus * (BPB_BytsPerSec / 4))) + (2 * FATSz) = DskSize  BPB_ResvdSecCnt + (2 * BPB_SecPerClus) Code: FATSz * ((BPB_SecPerClus * (BPB_BytsPerSec / 4)) + 2) = DskSize  BPB_ResvdSecCnt + (2 * BPB_SecPerClus) Code: FATSz = (DskSize  BPB_ResvdSecCnt + (2 * BPB_SecPerClus)) / ((BPB_SecPerClus * (BPB_BytsPerSec / 4)) + 2) This is different (and much simpler) than the MS version: fatgen103, page 21 wrote:
fatgen103, page 13 wrote: Note that on a FAT32 volume the BPB_RootEntCnt value is always 0, so on a FAT32 volume RootDirSectors is always 0. Here's the FASM code which works as either use16 or use32. Note edx:eax is the 64 bit total bytes size. Code: shrd eax, edx, cl ; ecx is BPB_BytsPerSec exponent, 512=9, 2048=11, 4096=12 shr edx, cl ; divide size by 512 for DskSize movzx ebx, WORD [BPB_ResvdSecCnt] sub eax, ebx sbb edx, 0 ; DskSize  BPB_ResvdSecCnt movzx ebx, BYTE [BPB_SecPerClus] add eax, ebx add eax, ebx ; + (2 * BPB_SecPerClus) jnc .1 mov eax, 1 ; max size 4GB1 .1: sub ecx, 2 shl ebx, cl add ebx, 2 ; (BPB_SecPerClus * (BPB_BytsPerSec / 4)) + 2 xor edx, edx div ebx ; (DskSize  BPB_ResvdSecCnt) / ((BPB_SecPerClus * (BPB_BytsPerSec / 4)) + 2) cmp edx, 0 adc eax, 0 ; need one extra sector if any remainder Format any size USB flash drive FAT32. Using a disk editor like HxD the following variables are located at the following offsets from the start of the first volume sector. Code: BPB_SecPerClus equ 13 ; BYTE BPB_ResvdSecCnt equ 14 ; WORD BPB_NumFATs equ 16 ; BYTE DskSize equ 32 ; DWORD FATSz equ 36 ; DWORD Do the math and check the FATSz as actually formatted. Edit: Added correction to code by revolution Edit: Added size of sector calculation and compensation for first two FAT entries. Last edited by Mike Gonta on 29 Mar 2011, 09:03; edited 2 times in total 

28 Mar 2011, 01:41 

< Last Thread  Next Thread > 
Forum Rules:

Copyright © 19992023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.