DOS Disk Information

See the disclaimer on the main page

For more information on disk drives and PC bootup, see the BIOS/hardware reference.

DOS hard drives may be 'partitioned' to form several 'logical drives' (which are normally each assigned their own drive letter by DOS). Only one partition at a time can be marked 'bootable'. The partition table information is contained in the master boot record (the true boot record, "MBR") of the drive, which resides on the first logical sector (of the first track or cylinder on the first head). That first sector also contains the MBR code, which determines the bootable partition and loads the boot sector (first logical sector) of that partition, executing it as if it was itself a boot record (loaded at the same location, registers contain the same values). It is possible to install several different operating systems on one computer in this way, especially if the standard MBR code is replaced in order to allow the bootable partition to be seleced at boot time.

There is a limit of four entries in the master partition table. DOS allows these entries to contain pointers to 'extended partition tables', whose format is exactly the same as for the main partition table except there is no boot code (the space normally reserved for the boot code is empty). All the extended partitions should exist within the space reserved by the extended partition entry - only two of the extended partitions are meant to be used, the first as a normal partition, the second as another extended partition (optional).

The DOS boot sector contains as a first instruction a 'jmp' (code 0EBh for DOS 3.x+) to the real code. The boot sector contains various information about the disk, including a BIOS parameter block, as well as some DOS startup code, which loads (part of) IO.SYS or the equivalent and passes control to it. The exact workings may be DOS specific and version specific.

Any sectors before the boot sector of a logical DOS drive are considered to be 'hidden' sectors. The DOS kernel does not interpret hidden sectors (it is up to the disk device drivers, which are usually internal to DOS anyway, to skip 'hidden' sectors). Normal floppy drives have 0 hidden sectors. Hard drive partitions will have a number reflecting their location on the drive. Note that the whole first head of the first cylinder is (usually) reserved for the partition table, even though it is only the first sector which is actually used.

Following the hidden sectors are 'reserved' sectors usually used only for the boot sector. Following this are the File Allocation Tables (FATs). The FATs should all be identical (there are normally two). They contain a map of cluster usage (the data area sectors are grouped into 'clusters'. The number of sectors per cluster does not vary for any particular disk, and depends on the number of sectors - DOS can only map a certain number of clusters; if there are more sectors than the maximum number of clusters, then more than one sector is assigned to each cluster). The FATs also mark bad clusters, and give the order of clusters for a file.

Following the last FAT is the root directory. The root directory is variable size but must be contiguos (and under DOS cannot normally change size once initiated). The root directory contains information about the files and directories branching from the root directory. All further directories are themselves stored as files, in the same format as the root directory.

Interestingly enough, the volume label for a floppy is usually stored within the boot sector, but the volume label for a hard drive is stored as a root directory entry and the space reserved in the boot sector is left blank with spaces. The DOS 'DIR' command returns the one in the directory if present, or the one in the boot sector if not.


Master boot record format

OffsetDescription
0000hCode to load and execute currently bootable partition.
01BEhPartition table entry #1
01CEhPartition table entry #2
01DEhPartition table entry #3
01EEhPartition table entry #4
01FEhBootable sector signature 55h, AAh (55h low)

Partition table entry format

Note that the head, sector and cylinder numbers are those which should be passed to BIOS. Thus, if BIOS is using translation (LARGE mode), the values may not represent the physical CHS values. Also, for large hard drives (> 8GB), the CHS values may be invalid; these values should generally be ignored and the absolute sector values used instead.

OffsetDescription
0000hBoot indicator. 0 - inactive, 80h - bootable
0001hBeginning head
0002hBeginning sector (in bits 0-5), and bits 9-8 of the beginning cylinder (in bits 7-6)
0003hBeginning cylinder (bits 7-0)
0004hSystem indicator
0005hEnd head
0006hEnd sector (in bits 0-5) and bits 9-8 of the ending cylinder (in bits 7-6)
0007hEnd cylinder (bits 7-0)
0008hDWORD absolute starting sector
000ChDWORD absolute ending sector

Beginning/ending head/sector/cylinder: These are the same values that should be used when accessing the partition via the BIOS INT 13H interface (i.e. they are logical CHS numbers as understood by the BIOS, not necessarily physical CHS numbers as understood by the drive hardware.

In determining the sector/head/track from an absolute sector number, the sector is incremented first (is the least significant portion), then the head, then the track/cylinder (most significant portion). Sector numbers start at 1, head/cylinder numbers start at 0.

Also, the 2 most significant bits of the (10 bit) cylinder number are stored in the 2 most significant bits of the byte at offset 02h/06h. The other bits in this byte form a 6 bit sector number. Thanks to Rick Ondrejicka for pointing out that I had originally missed this.

By convention, paritions always start on a cylinder boundary (that is, sector 1, head 0 of some cylinder. The exception is a partition starting in cylinder 0, which will start at head 1/sector 1. This usually leaves most of the first track (cylinder 0/head 0) unused; it contains only the MBR. This unused space is often used by boot manager software.

If a partition starts or ends at a cylinder address beyond what is representable in the partition table, convention seems to be to "max out" the relevant CHS values so that they are the highest legal values given the geometry of the drive (as represented by the BIOS INT 13H interace). It may be that all CHS values are maxed out (linux utilities do this) or just the cylinder number (Windows XP seems to do this).

System indicator: 0 = not defined/unknown, 1 = DOS 12-bit FAT, 2-3 = XENIX, 4 = DOS 16 bit FAT with 512 or less bytes/cluster (<32 MB), 5 = Extended DOS partition, 6 = large (bigger than 32MB) DOS partition with 16 bit FAT, >512 bytes/cluster.


DOS Boot Sector

Note that it is possible to determine if the extended information (DOS 4.0+) is available by examining the signature byte at offset 26h.

OffsetDescription
0000hJMP instruction, code 0EBh for DOS 3.x+
0003h(8 bytes) OEM name. Identifier of creator of boot record
000BhWORD bytes per sector
BIOS PARAMETER BLOCK
000DhBYTE Sectors per cluster
000EhWORD Reserved sectors
0010hBYTE Number of FATs
0011hWORD Maximum number of root directory entries
0013hWORD Total number of sectors
0015hBYTE media descriptor
0016hWORD sectors per FAT
(BPB ends)
0018hWORD sectors per track
001AhWORD number of heads
001ChWORD number of hidden sectors (see also next)
EXTENDED BOOT RECORD INFO (DOS 4.0+)
001EhWORD number of hidden sectors (high WORD)
0020hDWORD Total number of sectors
0024hWORD Physical drive number (as passed to BIOS)
0026hBYTE Extended information signature (29h)
0027hDWORD disk serial number
002Bh11 BYTEs volume label (floppys only, see main text)
0036h8 BYTEs file system. FAT12 or FAT16 (padded with spaces)

Bytes per sector: Must be an integer power of 2 (eg, 64, 128, 256). Floppy disks are normally 512 bytes/sector; most fixed disks are also 512 bytes/sector.

Total number of sectors: Excludes hidden sectors. If zero in the BPB, the field in the extended boot record information is used and vice versa.

Media descriptor: Used to give an indication of the media (disk) type. Normal values are 0 for an extended DOS partition, 0F0h for a (18 sector/80 track) 1.44MB 3 1/2 inch floppy, 0F8h for a hard drive, 0FDh for a (9 sector/40 track) 360KB 5 1/4 inch floppy (unverified) or a (9 sector/80 track) 720KB 3 1/2 inch (verified) , 0F9h for a (80 track 15 sector) 1.2MB 5 1/4 inch floppy. '0' seems to be the best way to go for anything else. The media descriptor byte doesn't appear to actually mean very much.


FAT

(Entries are either 12 or 16 bits)

First two entries: Reserved. The first byte of the first entry is also the media descriptor byte.

Further entries: (MAX is 0xffff for 16 bit fats, 0xfff for 12 bit fats)
0if the cluster is unused (free, available)
(MAX-7) to MAXLast cluster in file
(MAX-8)bad cluster
(MAX-15) to (MAX-8)reserved cluster
Anything else:Next cluster in file chain (this is the number of the appropriate entry in the FAT table, so #2 is the first non-reserved cluster)


Directory entry format:

Note that a directory is stored as a contiguos series of directory entries.

Note also that all subdirectories (but not the root directory) contain entries for the '.' (this subdirectory) and '..' (parent directory) directories, as displayed in a normal directory listing.

OffsetDescription
0(11 bytes) file name or (on hard disks) volume label. For file names, the first 8 bytes are the name before the extension (left justified, padded with spaces) and the final 3 bytes are the extension. If the first byte is 0, this entry is invalid and is the last entry. If it is E5h**, the file has been deleted. If it is 5, the first character is actually an 0E5h (but the file has not been deleted).
0BhFile attributes:
bit 0 - read only flag
bit 1 - hidden file flag
bit 2 - system file flag
bit 3 - volume label flag (indicates entry is a volume label)
bit 4 - file is a subdirectory (in same format as directory)
bit 5 - archive bit (file modified since last backup), set by DOS
bit 6 & 7 - reserved
0Ch(10 bytes) reserved
Time and date stamp give time of last file modification
16h(2 bytes) timestamp (bits 0-4 : seconds in two second increments, bits 5-10 : minutes, bits 11-15 : hours [from 0-23])
18h(2 bytes) datestamp (bits 0-4 : day of month, 5-8 : month, 9-15 : years since 1980)
1Ah(2 bytes) First cluster of file (2 = first cluster after root dir). A value of 0 is used in 'parent directory' ('..') entries to indicate that the parent is the root directory.
1Ch(4 bytes) File size in bytes.