FDOS/kernel

FAT32 loader installed by FreeDOS SYS with /OEM:EDR doesn't correctly pass the load unit in DL (and vice versa)

ecm-pushbx opened this issue · 1 comments

During my work on Enhanced DR-DOS's early boot stages I noticed that the EDR-DOS-specific load protocol expects the ROM-BIOS (int 13h) load unit in DL whereas FreeDOS load expects it in BL.

Studying the sources of the patched FreeDOS SYS delivered as EDR-DOS SYS v3.5 (source archive mirrored here), including their boot sector loaders, I found that the two different FAT32 loaders both were patched to set DL, instead of setting BL.

(The common part of the FreeDOS and EDR-DOS boot sector loader for FAT12/FAT16 sets both registers, exempting it from this bug.)

The upshot is that when installing a FAT32 boot sector loader using the FreeDOS SYS build and using the /OEM:EDR switch the loader will still set BL and generally not set DL correctly, breaking the load protocol expected by the older EDR-DOS kernels (corresponding to my 2023 August revision and earlier).

The same is true inversely: Installing a FAT32 loader using the EDR-DOS SYS build and using the /OEM:FD switch will lead to the loader not correctly setting BL.

This problem does not affect the lDOS iniload or lDOS drload stages as these never use the load unit passed in a register, opting to read it from the boot sector's BPB New field for the load unit instead. The 2023 December build of my EDR-DOS repo uses one of these lDOS stages as the first stage after the sector loader so they aren't affected by being loaded with the wrong load unit register.

SYS doesn't track which load unit register to use (for the FAT32 FreeDOS-native loaders):

typedef struct DOSBootFiles {

The FreeDOS-native FAT12/FAT16 loaders set both registers:

mov bl,dl ; drive (left from readDisk)

The FAT32 CHS 8086 loader sets BL only, patched for EDR SYS to DL only:

boot_success:

Same for the FAT32 LBA 386 loader:

boot_success: mov bl, [drive]

This bug may be masked by how the most common usage of the load unit register happens in drbio/init.asm: https://hg.pushbx.org/ecm/edrdos/file/465be5fcbb65/drbio/init.asm#l839

	test	al,al			; test the boot drive
	 jz	floppy_boot		; skip if floppy boot
	mov	al,2			; it's drive C:
floppy_boot:
	mov	init_drv,al		; set boot drive

FAT32 isn't usually used on diskettes. So any nonzero value in DL will lead to setting the drive C: as the boot drive, only the value zero would unexpectedly set drive A: instead.