GRLDR cannot be loaded when stored on a high cluster number
1ras opened this issue · 5 comments
It seems that a boot record written with bootlace.com 0.4.6a cannot load GRLDR when stored above a certain cluster number somewhere above 32768. File system is FAT16 on a hard drive.
Here is what happens:
Here is a disk editor screenshot, the last column is the start cluster:
The file system is defragmented and all GRLDR.* files are identical (identical MD5 checksum). I rename one GRLDR.* file at a time to GRLDR (without extension) and see if it can be loaded.
From the screenshot, GRLDR.3 till GRLDR.6 are able to load and GRLDR.7 till GRLDR.19 are unable to load.
The issue depends on the bootlace.com version that was used to write the boot sector.
Every 0.4.6a bootlace.com version is affected:
0.4.6a-2012-01-01 FAILS
0.4.6a-2012-12-31 FAILS
0.4.6a-2013-11-30 FAILS
latest FAILS
Where 0.4.5c bootlace.com works perfectly fine:
0.4.5c-2015-05-18 WORKS
0.4.5c-2016-01-18 WORKS
After many tests I belief that the behavior is related to the cluster number and the limit is somewhere around 32768.
How many sectors per cluster?
4096 bytes per cluster, which means 8 sectors of 512 bytes
The issue is independent of the cluster size and only depends on the cluster number. Here are the steps to replicate the issue on Linux with a 32K cluster size:
# This is the device of the USB flash drive we use (2 GB minimum size for 32K cluster size)
# ALL DATA ON THIS DEVICE WILL BE LOST !
DEV=/dev/sdX
# Write new partition table - ALL DATA ON DEVICE WILL BE LOST !
echo ",+1900M,6,*" | sfdisk -w always -W always $DEV
# Format partition with FAT16 - ALL DATA ON DEVICE WILL BE LOST !
mkdosfs -v -F 16 ${DEV}1
# Make device bootable
bootlace64.com $DEV
# Mount partition and cd to it
mount $[DEV}1 /mnt
cd /mnt
# Copy grldr
cp /location/of/grldr grldr
# Consume approx. 32.400 clusters (this takes a while)...
mkdir dir; for N in $(seq 1 32400); do echo > dir/$N; done
# Duplicate grldr 50 times...
for N in $(seq 1 50); do cp grldr grldr.$N; done
# Check the start clusters of the grldr files (c=cluster#)
sync; fatcat ${DEV}1 -l /
# Choose one which does not fit entirely below 32768 clusters
# and replace it with the working grldr file by renaming
mv grldr grldr.0
mv grldr.XX grldr
# Unmount
cd
umount /mnt
# Try booting
Results in my case (replicated with Linux KVM/qemu):
$ sync; fatcat ${DEV}1 -l /
(...)
f 15/8/2023 11:51:44 grldr.31 c=32745 s=323037 (315.466K)
f 15/8/2023 11:51:44 grldr.32 c=32755 s=323037 (315.466K)
f 15/8/2023 11:51:44 grldr.33 c=32765 s=323037 (315.466K)
f 15/8/2023 11:51:44 grldr.34 c=32775 s=323037 (315.466K)
f 15/8/2023 11:51:44 grldr.35 c=32785 s=323037 (315.466K)
(...)
grldr.32 (starts at cluster 32755):
grldr.33 (starts at cluster 32765 but does not entirely fit below cluster 32768) and grldr.34 (starts at cluster 32775):
I also added a menu.lst to cluster 32945 to see if grldr itself is affected, but fortunately grldr is able to load the menu.lst.
I also tested with 120 MB (2K cluster size) and partition type "e" (FAT16X LBA). The partition command in this case is:
# Write new partition table - ALL DATA ON DEVICE WILL BE LOST !
echo ",+120M,e,*" | sfdisk -w always -W always $DEV
The cluster consumption is different, so we need to reserve fewer clusters ourselves:
# Consume approx. 28.000 clusters (this takes a while)...
mkdir dir; for N in $(seq 1 28000); do echo > dir/$N; done
Everything else is the same and the results are the same.
I can confirm that issue is resolved.
Thanks for providing grub4dos!