User Tools

Site Tools


blog:pushbx:2023:0108_freedos_256_spc_bootimg_ldebug_updates_ldos_boot_optimisations

FreeDOS 256 spc, bootimg/lDebug updates, lDOS boot optimisations

2023-01-05

Yesterday saw some more activity after the prior blog entry.

FreeDOS kernel and boot loaders: Support for 256 Sectors per Cluster

This is a feature originated by the Enhanced DR-DOS project. Basically, when the byte field for "sectors per cluster" in the BPB contains 0, this is treated as indicating 256 sectors per cluster. Other than this special encoding the support comes naturally, especially if the kernel is already able to handle 128 sectors per cluster. (Which ends up with 64 KiB/cluster on the usual 512 Bytes per sector.)

The FreeDOS kernel needed very little changes to make it work with 256 sectors per cluster. In fact, only one small patch in the entire kernel was strictly necessary.

The most changes were actually in the boot sector loaders: oemboot for FAT12/FAT16, boot for FAT12/FAT16, boot32 for FAT32 CHS, boot32lb for FAT32 LBA. The only use of the sectors per cluster value needed two more instructions to transform a byte of 0 to the word value 256, and otherwise zero-extend the byte value.

Due to the change, the hardcoded LBA detection offsets of boot.asm changed, and were subsequently updated in SYS.

oemboot ran out of space in one of its variants. I found a simple patch that freed up 2 bytes. Namely, lea was used with a large displacement from bp which evaluated to constant values, but took 4 bytes per instruction to do so. The optimisation is to load the constant values with mov instead, taking only 3 bytes per instruction.

bootimg stress testing

The bootimg script was used to build test images for the FreeDOS kernel change, building FAT12, FAT16, and FAT32 images with 128 or 256 sectors per cluster.

The good news is that the lDOS boot loaders and the debugger handled such file systems just fine. The support prepared absent testing did work.

Creating a file system image with a typical FAT32 file system and 128 KiB per cluster proved difficult. With nearly 100_000 clusters, the script was killed by the server's operating system. Not much of a surprise: 128 * 1024 Bytes/cluster times 100_000 clusters works out to more than 12_800_000_000 Bytes (> 12 GB).

One fix was to use bootimg's -D_FULL=0 option. This writes only a partial image consisting of the reserved area, FATs, directories and actual file data. Most of the data area is not written.

The other solution is to specify fewer clusters than the 64 kilo binary expected for FAT32. This required a patch to bootimg, adding the option _ERROR_SMALL32 which can be disabled to allow creating a small FAT32 file system.

The kernel already worked with small FAT32 out of the box. So did the lDOS loaders. Not so lDebug, the debugger checked that a small file system is not FAT32. This check was changed to accept rather than forbid small FAT32. (A similar dispatching in FreeDOS SYS is yet to be fixed.)

lDOS boot optimisations

Today the boot sector loaders were optimised. The boot32 function clust_to_first_sector had its protocol changed to not preserve the cluster number in another register pair. Instead, the two callers now push dx:ax before the call. Further, the function sets up cx with the adjusted sectors per cluster count.

A similar change in boot was to calculate the adjusted sectors per cluster only at the site it is used. This saves 4 bytes in each of the FAT12 and FAT16 loaders. The idea was gleaned from the 256 spc changes to the FreeDOS loaders, as it was apparent that only one access to the variable happened. (This access uses the result both to multiply the cluster number into a sector number, and to loop over all sectors of the current cluster.)

You could leave a comment if you were logged in.
blog/pushbx/2023/0108_freedos_256_spc_bootimg_ldebug_updates_ldos_boot_optimisations.txt · Last modified: 2023-01-08 16:39:58 +0100 Jan Sun by ecm