]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[build] Work around syslinux bugs in FAT cluster counting
authorMichael Brown <mcb30@ipxe.org>
Thu, 26 Mar 2026 12:51:20 +0000 (12:51 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 26 Mar 2026 13:25:20 +0000 (13:25 +0000)
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>
src/util/genfsimg

index 0309c9134a7643b9125a064e29cd459ff44a9e75..54e9d4354849299ff05f33f16d02b3b71bc6e3ef 100755 (executable)
@@ -349,7 +349,14 @@ if [ -n "${FATIMG}" ] ; then
        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"