This is a consequence of a buggy overflow check.
Internally, MS-DOS uses logical block addressing to access file systems. Since version 4.0, MS-DOS uses 32 bits for sector addresses in order to support disks larger than 32 MiB (i.e. than 65536 sectors). To ensure all sectors are addressable with 32 bits, MS-DOS tries to compute the address of the last sector as (start − 1) + count (where start and count are the last two fields in the MBR partition table entry); if there is an overflow at the end of the calculation, a flag is set at offset 0x1f in a data structure the RBIL calls the ‘drive data table’ that disables all accesses to the disk. Subtracting 1 from the starting sector number prevents triggering overflow when the final sector’s number is exactly 4294967295 (232 − 1)… but it also ensures that if the starting sector is zero, this computation always overflows, as 0 − 1 is 4294967295 in 32-bit unsigned arithmetic. Apparently it didn’t occur to Microsoft that someone might want to create such partitions. In earlier MS-DOS versions there was no problem, as the overflow check instead tested whether the upper 16 bits of the 32-bit result are zero, not whether there was any overflow at all. Since MS-DOS and PC DOS share the same codebase, this bug is also present in the latter (and is still around in later versions only developed by IBM).
One may wonder why Microsoft didn’t drop the check entirely, and why did they keep around code to support partitions ending exactly on the 2 TiB boundary, given that the CHS addressing scheme used by the interrupt 0x13 services to which DOS delegates disk accesses only uses 24 bits (while wasting some of that addressing space by using 1-based indexing for the last coordinate!), so it can only actually address 8064 MiB. Your guess is as good as mine.
Later versions of MS-DOS (those incorporated into Windows 9x) added support for LBA disk access for partitions marked with an appropriate type identifier, which would then make the overflow check serve some purpose… except that the check has no effect on those, making it entirely pointless again. (The extended interrupt 0x13 services use 64-bit addressing, and I have superficially tested MS-DOS 7.x to support 64-bit sector numbers on LBA partitions just fine, by mounting a sparse disk image in a VM.)
As for fixes, you can address the bug either by changing the disk image or by changing DOS.
As previously mentioned, MS-DOS 7.x and 8.x are not affected by this issue when accessing disks in LBA mode. If you only care about the file system being readable on (relatively) modern systems, you can simply change the partition type ID to 0x0c
(FAT32) or 0x0e
(FAT12 or FAT16). This disables the 32-bit overflow check and makes the partition accessible.
You can patch IO.SYS to fix the overflow bug. Open IO.SYS (or IBMBIO.COM for PC DOS) in a hex editor, and look for the following byte sequence:
2D 01 00 83 DA 00 26 03 47 08 26 13 57 0A 73 05
Then replace it with:
26 03 47 08 26 13 57 0A 73 0B 09 D0 74 07 90 90
Though the same overflow check is also present in MS-DOS 7.x and 8.x (i.e. Windows 9x), the opcodes are encoded differently. Additionally, to patch MS-DOS 8.0 in particular (i.e. Windows Me) you will have to uncompress IO.SYS first. In those versions, look for this sequence:
83 E8 01 83 DA 00 03 47 08 13 57 0A 73 06
and replace it with:
03 47 08 13 57 0A 73 0C 09 D0 74 08 90 90
This replaces the following instruction sequence:
268B4704 8B4704 mov ax, [(es:)bx+?_start_lo]
268B5706 8B5706 mov dx, [(es:)bx+?_start_hi]
2D0100 83E801 sub ax, 1
83DA00 83DA00 sbb dx, 0
26034708 034708 add ax, [(es:)bx+?_count_lo]
2613570A 13570A adc dx, [(es:)bx+?_count_hi]
7305 7306 jnc ?_ok
with the following:
268B4704 8B4704 mov ax, [(es:)bx+?_start_lo]
268B5706 8B5706 mov dx, [(es:)bx+?_start_hi]
26034708 034708 add ax, [(es:)bx+?_count_lo]
2613570A 13570A adc dx, [(es:)bx+?_count_hi]
730B 730C jnc ?_ok
09D0 09D0 or ax, dx
7407 7408 jz ?_ok
90 90 nop
90 90 nop
Instead of subtracting 1 to compute the last sector, this computes the first sector after the partition, and additionally accepts a wrapped-around result of 0 as valid. This avoids overflow when the starting sector is zero, keeps the corner cases exactly the same otherwise, and even leaves two instruction bytes to spare. (Another victory for Dijkstra, I suppose.) You can keep using DOS with confidence on terabyte-sized disks, if by some miracle you manage to address their sectors with 24-bit CHS. (Yes, you may just patch out the subtraction, or the entire check. But I’ll stay on the safe side just in case this actually does something useful that I overlooked.)