DOS Internals page 601--607 quote
2023-02-22T17:05:34+01:00 Wed
2023-02-22T18:24:26+01:00 Wed
2023-02-22T18:38:03+01:00 Wed
Hard Disk Boot Sectors
Starting with DOS 5, IO.SYS subjects hard disk boot sectors to some preliminary plausibility checks:
- The jump instruction at offset 00h must be either a JMP NEAR (opcode E9h) or JMP SHORT (opcode EBh), the latter requiring a NOP to make up the three bytes of the field;
- The media descriptor at offset 0Ah in the BPB on disk must be ≥ F0h;
- The number of bytes per sector given at offset 00h in the BPB on disk must be 0200h;
- The number of sectors per cluster given at offset 02h in the BPB on disk must be a power of 2.
If any of these conditions are not satisfied, then IO.SYS configures the partition as a device unit (so it will ultimately become a DOS drive), but the representation built for the disk is a default, based wholly on information already obtained from the partition table or from querying the BIOS about the disk drive's physical structure. In addition, IO.SYS disables access to the drive, awaiting the deliberate action of software that establishes the disk's true format. This plausibility check is probably not implemented as a defensive measure but instead offers the opportunity to replace the native DOS file systems based on 12-bit and 16-bit FAT entries while still retaining the default block device driver in IO.SYS for low-level disk operations.
A primary reason to construct a device driver unit but disable access is that the partition might not have been formatted yet; for example, the FORMAT utility calls the generic IOCTL service to enable the access flag (int 21h function 440Dh minor code 47h, described later) after it has successfully initialized the structures required to support a DOS file system on the partition.
OEM Name and Version
DOS 5 is also the first version that does not tie boot sector recognition to the OEM name at offset 03h. This is an important freedom because if a disk's boot sector has an unknown OEM name, the other fields describing the disk's characteristics are disregarded. Instead the disk is assigned a default format based essentially on its total capacity (as before, but typically not with the provision for disabling access). In versions 3.30 for instance, IO.SYS accepted the disk format only if the OEM field started with the letters 'IBM'. DOS 4 extended the list to 'IBM', 'MSDOS', and 'OS2'. The objective is presumably to avoid boot sectors formats with known problems, and to this end DOS 3.30 and DOS 4 also checked the last characters of the OEM field for a version number.
It is clearly unacceptable that third-party format programs be rendered ineffective for not having the "right" name -- certainly not if DOS is meant to work straight "out of the box." DOS 5 resolves the issue by concentrating solely on the version number assumed to conclude the OEM field. Specifically, the last character should be a single-digit minor version number, preceded by a period and further back by digits denoting the major version. With this interpretation
- major versions that are multiples of 10 other than 10 itself or 20 are regarded as unknown and access to the drive is disabled (in the sense described earlier);
- with the exception of version 2.0, all versions numbered below 3.1 are regarded as unknown.
Accepted Hard Disk Formats
If the boot sector meets the criteria for recognition, then fields in the BPB are accepted as accurate descriptions of the disk layout -- up to a point. The BPB maintained by IO.SYS in memory for a disk does not necessarily match the BPB on disk. The importance of understanding this cannot be overstated: for all disk access, it is the BPB in memory that counts.
Two FAT copies are assumed, regardless of the value given in the BPB on disk. Less important, the media descriptor for hard disks is taken as F8h, again independent of the BPB on disk. The number of sectors per track and the number of heads are taken as drive characteristics returned by int 13h function 08h, not from the BPB on disk. Likewise, the number of hidden sectors is adopted from the relevant partition table -- as it should be, since these sectors lie outside the storage space used by the DOS drive. In contrast, the total capacity in sectors is read from the BPB in preference to the value in the partition table, unless the BPB specifies zero (in both the word and dword fields).
That IO.SYS does not adopt a particular BPB field does not mean that the value on disk is meaningless, just that IO.SYS takes no notice of it. For instance, the standard boot code must calculate the physical parameters from which to load at least the first few sectors of IO.SYS and therefore needs to know the number of hidden sectors. It reads the field in the BPB -- after all, the code must be small and is hardly in a position to hunt for fields in a partition sector.
The signature byte at offset 26h may have the magic value 29h -- to denote an extended BPB that runs on to provide a serial number, a volume label, and a file system ID. More generally, the magic value indicates a modern format (the standard boot code, for instance, does not consult the 32-bit field for total sectors unless it also finds the magic number). More detail is given in the "Media Identifiers" section, but for now it should be observed that IO.SYS adopts the identifiers from the boot sector if it sees the magic value. In practice, the media identifiers kept in memory by IO.SYS are not consulted for hard disks.
IO.SYS calculates the number of whole sectors available for data, on the basis that the storage space is devoted to some number of reserved sectors, followed by the two FATs and a root directory. If the equivalent number of clusters is less than 0FF6h, then the DOS file system will be able to cope with 12-bit FAT entries; if not, then 16-bit FAT entries are required. The drive is invalidated (beyond resuscitation via the Access Flag) if the number of clusters deduced for a recognized disk format overflows 16 bits.
For the sake of completeness, observe that both DOS 4 and DOS 5 make a special case for modern disk formats (that is, ones with the magic value 29h) that indicate
no FAT copies. In this case, IO.SYS adopts the BPB from disk without alteration, save only that DOS 5 retains the sector capacity from the partition table if the value in the BPB is zero. Calculations related to FATs are redundant to this special case and skipped.
Unrecognized Hard Disk Formats
An ignominious fate awaits any hard disk whose boot sector DOS dismisses as having an unknown format. The disk characteristics adopted for the remainder of the session depend entirely on the properties already obtained from the partition table and from int 13h function 08h (Get Drive Parameters). The BPB in the boot sector is completely distrusted. Of course, this behaviour is an important defence if the partition has not yet been formatted as a DOS drive, in other words, if a DOS boot sector with a valid BPB really hasn't been written into place.
As noted already for recognized hard disk formats, some fields in the BPB on disk are ignored anyway, but this treatment of unknown formats is especially inflexible. The following disk characteristics are imposed uniformly:
Bytes per sector 512
Reserved sectors 1
Number of FAT copies 2
Root directory entries 512
Media Descriptor F8h
The number of sectors per cluster and the size of FAT entry are determined from the total capacity in sectors according to the following rules:
Total capacity Equivalent in Sectors per Size of FAT
in sectors bytes cluster entry
≤ 0FF5h * 8 ≤ approx 16MB 8 12-bit
≤ 64K * 4 ≤ 128MB 4 16-bit
≤ 64K * 8 ≤ 256MB 8 16-bit
≤ 64K * 16 ≤ 512MB 16 16-bit
≤ 64K * 32 ≤ 1GB 32 16-bit
≤ 64K * 64 ≤ 2GB 64 16-bit
≤ 64K * 128 ≤ 4GB 128 16-bit
The number of sectors per FAT is deduced by solving an equation. The problem is that the FAT must have enough sectors to hold as many entries as there are clusters in the disk's data area, whose size is in turn affected by the number of sectors in each FAT copy. Let
b = the number of reserved sectors at the start of the disk (boot sectors)
f = the number of sectors per FAT
r = the number of sectors allowed for the root directory
x = the number of sectors available for storing file data
t = total disk capacity in sector
then the disk's logical structure gives the relationship
t =
b + 2
f +
r +
x
A FAT consisting of
f sectors can represent at most 256
f - 2 clusters of data (using 16-bit FAT entries and allowing for the first two FAT entries which do not correspond to clusters in the data area), so the FAT contains no wasted sectors if and only if
[256(
f - 1) - 2]
s <
x ≤ (256
f - 2)
s
where
s denotes the number of sectors per cluster. The solution, given for the benefit of those who write software that formats disks or inspects boot sectors (as part of a disk repair service, for instance), is
f = the least integer greater than or equal to (
t -
b -
r + 2
s) / (256
s + 2)
which is very nearly the same algorithm implemented by Microsoft. With 12-bit FATs, the solution is complicated by the way that FAT entries need not fit neatly into sectors and is not taken up here, although it is similar.
Floppy Disk Drives
[...]
Floppy Disk Boot Sectors
In the normal course of reading from and writing to floppy disks, these default formats play no role, provided that a reliable format description can be obtained from the floppy disk's boot sector. To be accepted, a floppy disk boot sector must pass the following tests, similar to those applied for hard disks:
- The jump instruction at offset 00h must be either a JMP NEAR (opcode E9h) or JMP SHORT (opcode EBh), the latter requiring a NOP to make up the three bytes of the field; to support older formats, the first byte may be 69h.
- The media descriptor at offset 0Ah in the BPB on disk must be ≥ Fh.
Just as with hard disks, however, some elements of the disk's own description of its format are countermanded. For instance, the number of FATs is always taken to be two, whatever the value in the corresponding BPB field. Readers who doubt the truth of this assertion (and have perhaps been doubting it ever since it was advanced for hard disks) are invited to test it with a disk editor. Take a newly-formatted 360K disk, make the few alterations required for a third FAT (even to the point of changing the media descriptor bytes to F0h for unknown format), exit to DOS, remove the disk from its drive, and execute the
dir command for the drive in question. The resulting critical error forces the DOS kernel to request a BPB rebuild on the next access, so restore the disk and retry -- only to find the third FAT being treated as the root directory.
The complete picture is that IO.SYS enforces the following characteristics for floppy disks, ignoring the values given in the boot sector's BPB:
Bytes per sector 512
Reserved sectors 1
Number of FAT copies 2
Hidden sectors 0
In addition, the number of root directory entries
is read from the BPB on disk, but only modulo 256, so fiddling with the floppy disk boot sector in the hope of increasing the root directory's capacity beyond 240 would be a loser from the outset.