The syslinux function check_fat_bootsect() performs some sanity checks
to ensure that the filesystem type string (e.g. "FAT12") is correct
for the total number of clusters in the FAT. There is unfortunately a
bug in its calculation of the number of sectors occupied by the root
directory, which causes it to underestimate the number of sectors by a
factor of 32.
When the total number of clusters is close to the FAT12 limit of 4096,
this bug can cause syslinux to erroneously report that the filesystem
has "more than 4084 clusters but claims FAT12".
Work around this bug by selecting an explicit cluster size in order to
avoid potentially problematic cluster counts. We default to using 4kB
clusters, doubling to 8kB if using 4kB would result in a total cluster
count near 4096 (the FAT12 limit) or near 65536 (the FAT16 limit).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
FATALIGN=$(( FATHEADS * FATSECTS ))
FATCYLS=$(( ( FATSIZE + FATALIGN - 1 ) / FATALIGN ))
FATSIZE=$(( FATCYLS * FATALIGN ))
- FATARGS="-t ${FATCYLS} -h ${FATHEADS} -s ${FATSECTS}"
+ FATCLUST=8
+ if [ "${FATSIZE}" -eq $(( FATCLUST * 4096 )) -o \
+ "${FATSIZE}" -eq $(( FATCLUST * 65536 )) ] ; then
+ # Avoid cluster counts close to the FAT12/FAT16 limits to
+ # work around syslinux bugs
+ FATCLUST=$(( FATCLUST * 2 ))
+ fi
+ FATARGS="-t ${FATCYLS} -h ${FATHEADS} -s ${FATSECTS} -c ${FATCLUST}"
else
FATSIZE=2880
FATARGS="-f 1440"