CURRENT WORK ITEM - PREVIEW ONLY

BPB

The BPB, standing for BIOS Parameter Block, is the structure through which the DOS kernel is told about a disk drive or about media (disks) that are accessed through a disk drive. In the context, a disk drive is a device for accessing block storage that is organised according to one or another variant of DOS’s built-in File Allocation Table (FAT) file system. The BPB is specialised to describing the larger-scale features of this organisation—what might nowadays be called the file-system metadata.

Inevitably, the BPB is used in other circumstances that can benefit from the same or similar description. Most notable is that the BPB is usefully saved at a well-known position on the disk so that the file-system metadata that the kernel is to use for correctly accessing files on the disk can be known with some confidence instead of having to be calculated, inferred, guessed or trusted to the user’s recognition. Saving a BPB on each disk was not the original practice but finding one at offset 0Bh in the boot sector soon became the standard expectation, never of the DOS kernel but certainly of its built-in block device driver.

Many writers about DOS, and even specifically of DOS history, would have it that being on the media is a defining characteristic of the BPB. See, for instance, the opening sentence of Wikipedia’s article on the BIOS parameter block (today, 29th October 2021). However convenient this may be from modern perspectives, such as programming newer operating systems to use disks that were formatted for DOS or to format disks for use by DOS, it was not DOS’s perspective. This page that you read now is concerned solely with the BPB as understood by the DOS kernel. It ignores interpretations that are imposed retrospectively, except to dismiss them as unreasonably unhistorical. If ever these notes expand to take in the BPB as interpreted on disk, it will be as separate material about the boot sector. Note that this separation is not my own revisionism: it was well established when DOS was current, as in the Microsoft® MS-DOS Programmer’s Reference : version 5.0, ISBN 1-55615-329-5, by Microsoft Press in 1991, which has its definitions of the BPB and the BOOTSECTOR at opposite ends of the book.

An inevitable side-effect of fixating on the BPB only as observed on disks is to miss its origin.

Availability

The BPB is as old as DOS. Indeed, it is at least as old as the 86-DOS version 1.00 that PC DOS 1.00 was developed from.

True, no BPB is known to have been stored on any disk’s boot sector before PC DOS 2.00 became available, and neither is the BPB from DOS’s first version known to have been referred to as a BIOS Parameter Block until version 2.00. Yet far from not existing earlier, the BPB is essential to DOS’s disk I/O through all versions 1.xx.

Even if this had stayed obscure in the mists of pre-history because nobody had bothered to disassemble the system files from PC DOS 1.00, it ought to be well known by now given Microsoft’s publication of source code for MS-DOS 1.25 in 2014 at the Computer History Museum and in 2018 on GitHub. Even without source code, there’a big hint in the name. It’s not a Boot Sector This or Boot Sector That or a Boot Parameter Block or a Boot Anything. Why has it instead always been specifically a BIOS Parameter Block?

Name

The name BIOS Parameter Block, along with its abbreviation to BPB, is well established by formal documentation as early as IBM’s Disk Operating System manual for PC DOS 2.00 (part 6936752, January 1983), but if the BIOS in this name wasn’t already a mis-direction in 1983, it soon would be. Since at least the mid-1980s, what the term BIOS has meant for all practising DOS programmers, and perhaps even for most computer users, is the system software that is pre-installed in ROM with the IBM Personal Computer (PC) or with computer systems that offered some sort of PC compatibility. This BIOS certainly has a role in disk I/O but none in the naming of the BPB.

The BIOS that names the BPB is what eventually became the file that DOS users know as IO.SYS or IBMBIO.COM. Already in the first edition of the Disk Operating System manual (part 6172220, August 1981) for the IBM PC , this file was described as the “Read-Only Memory (ROM) BIOS interface module” but also as the “DOS BIOS”, the one claiming the term BIOS for IBM’s firmware, the other acknowledging older usage. Long before the PC existed, an operating system named CP/M (for a different processor) had established an architectural separation of the operating system into two parts. A lower-level component is specially adapted to each computer system’s hardware, or is even written afresh. It abstracts the hardware as an I/O System so that a higher-level component can be independent of the hardware and thus be the same operating system kernel to all programs. The CP/M names for these two components are the BIOS and the BDOS.

The term BDOS seems never to have caught on in DOS programming, but the term BIOS for the lower-level I/O system stuck for many years, either distinguished from the ROM BIOS as the DOS BIOS, or as just “the BIOS” but in contrast to “the DOS” or to “86-DOS” or “MS-DOS”. Thus does the published source file IO.ASM for building IO.SYS for various computer systems from Seattle Computer Products (SCP) define a macro BIOSSEG for the “I/O system segment” and compute a DOSSEG as the “segment to use for 86-DOS”. Thus does the published source file MSDOS.ASM for building MSDOS.SYS as a generic DOS kernel define a segment named SEGBIOS with entry points whose names all start with BIOS and whose use comes with such comments as “See what BIOS has to say” and “Calls BIOS to perform disk read.”

To know why the BPB is the BIOS Parameter Block, ask who it is in DOS version 1.xx who tells the DOS about the disk drives and the media they may contain.

Use

To the DOS kernel in version 2.00 and higher, the BPB is a block device driver’s description of a drive or disk. The kernel obtains such descriptions as output from the driver’s Init and Build BPB functions (00h and 02h, respectively). The Init function is of course called when initialising a block device driver. Success provides one BPB for each device unit, in effect, to describe each of the driver’s drives. The kernel calls the Build BPB function arbitrarily often, typically after a Media Check function (01h) answers negatively, to get a BPB for a specified unit’s current contents, i.e., the disk. Either way, the kernel uses the BPB as input for preparing or updating the DPB (Drive Parameter Block) that it keeps for each drive. It even exposes the relevant code to DOS programs, specifically through int 21h function 53h (apparently intended, at least at first, only for initialising block device drivers at the direction of a device statement in CONFIG.SYS).

See that nowhere in this interface between the DOS kernel and its device drivers must a BPB that’s produced for a disk have been on the disk. Nowhere does the interface require that a BPB has even the slightest role in the device driver’s possibly substantial work for reading from or writing to the disk, or for doing whatever else it is that a device driver might do with a disk—except to describe the disk to the kernel.

Obviously, a device driver’s implementation can be much easier if this BPB is used internally too, but no rule requires it and some advantage can be gained from giving the kernel a logical picture of the disk that differs from the physical. For instance, when the BPB had only a 16-bit member for the disk’s capacity in sectors, disks that have 512-byte sectors but are larger than 32MB could be accommodated by a device driver which describes the disk to the kernel as having 1024-byte sectors (or larger) and translates the kernel’s I/O requests to the 512-byte sectors of the (ROM) BIOS’s int 13h interface.

Before version 2.00, there are no device drivers. The DOS kernel learns about disk drives only from the DOS BIOS and only during the kernel’s initialisation. For this, the kernel is given an initialisation table. Within are pointers to the DOS BIOS’s description of each disk drive. In published source code for the DOS BIOS, both for 86-DOS (DOSIO.ASM) and for MS-DOS 1.25 (IO.ASM), each such description is labelled but its contents are defined just as a succession of bytes and words with no formal structure. Yet plainly each of these descriptions is an early form of what is later known as the BPB. Its passing to the kernel at initialisation in version 1.xx naturally developed into the output from the initialisation request of block device drivers when version 2.00 introduced installable device drivers.

Layout

Microsoft’s first known representation of the BIOS Parameter Block as a structure in a programming language is in a header named DOSSYM.ASM among the published source files for MS-DOS 2.11 which Microsoft published concurrently with those for MS-DOS 1.25. The structure is then named BPBLOCK.

Offset Size or Type Name Description Versions
00h word BPSECSZ Size in bytes of physical sector all
02h byte BPCLUS Sectors/Alloc unit all
03h word BPRES Number of reserved sectors all
05h byte BPFTCNT Number of FATs all
06h word BPDRCNT Number of directory entries all
08h word BPSCCNT Total number of sectors all
0Ah byte BPMEDIA Media descriptor byte 2.00 and higher
0Bh word BPFTSEC Number of sectors taken up by one FAT 2.00 and higher

The “Alloc unit” of Microsoft’s comment is also, if not more commonly, referred to as a cluster. The reserved sectors are those at the start of the disk which are no business of the kernel’s. Typically, and advisedly but not necessarily, they include a boot sector. By definition, they run up to but not including the first FAT. This begins the file system’s metadata, which is the given number of FATs and then a directory that is large enough for the given number of entries. Each FAT must be a whole number of sectors. So too must the directory. Computing how many whole sectors, especially for the FAT, is non-trivial and inevitably has quirks. DOS version 2.00 and higher extend the BPBLOCK to specify the FAT’s size in sectors.

The IBMBIO.COM for PC DOS 1.00 has the one hard-coded BPB for all the four diskette drives that it can possibly indicate to the kernel. The hard coding is for what has ever since been the standard 160KB diskette: 512-byte sectors, 1 sector per cluster, 1 reserved sector, 2 FATs, directory capacity of 64 32-byte entries, and disk capacity of 320 sectors. The kernel in PC DOS 1.00 can work with other formats, but it will never learn of them except if booted with a replacement IBMBIO.COM.

Most users, of course, did not have a replacement IBMBIO.COM—certainly not at the time and apparently not even now as hobbyists who might draw on decades of their own and others’ experience to write a replacement. For PC DOS 1.10, users were treated to a small but not insignificant reorganisation of the initialisation interface between IBMBIO.COM and IBMDOS.COM so that each disk drive was known to support either of two disk formats (from having two heads and the flexibility of using either one or both for one-sided and two-sided disks). Each BPB is still hard-coded, the second differing in having 2 sectors per cluster, a directory capacity of 112 entries and disk capacity of 640 sectors.

Not only do the two members at offsets 0Ah and 0Bh have no meaning to the kernel in versions before 2.00 but they are not used internally by the I/O system. This is most plain in PC DOS 1.10 whose two hard-coded structures for the two expected formats are consecutive.

Though the BPBLOCK is the oldest definition that Microsoft has yet published, the first that Microsoft published openly is named BPB. It is an assembly-language definition in the Microsoft® MS-DOS Programmer’s Reference : version 5.0, ISBN 1-55615-329-5, for Microsoft Press in 1991. Earlier texts from Microsoft, including the same reference but for earlier versions, present the structure but only to describe its members in words, not with a definition in any programming language.

Offset Size or Type Name Versions
00h word bpbBytesPerSec all
02h byte bpbSecPerClust all
03h word bpbResSectors all
05h byte bpbFATs all
06h word bpbRootDirEnts all
08h word bpbSectors all
0Ah byte bpbMedia 2.00 and higher
0Bh word bpbFATSecs 2.00 and higher
0Dh word bpbSecPerTrack 3.31 and higher
0Fh word bpbHeads 3.31 and higher
11h dword bpbHiddenSectors 3.31 and higher
15h dword bpbHugeSectors 3.31 and higher

The three members at offsets 0Dh, 0Fh and 11h are irrelevant to the DOS kernel. They have followed the BPB in boot sectors since version 2.00 (the last of them being originally only a word) but are explicitly excluded from the BPB as presented in boot sectors in Microsoft documentation up to and including the Programmer’s Reference for version 4.0. There’s surely no mistaking this point in IBM’s Disk Operating System manual for PC DOS 2.00:

The three words at the end are optional. DOS does not care about them because they are not part of the BPB.

When version 3.30 anticipated disks with too many sectors for the word at offset 08h, the practical value of having the BPB in the boot sector would have been lost if the BPB for the DOS kernel were extended without allowing for what follows the BPB when stored in a boot sector. The Programmer’s Reference for version 3.30 adds the 32-bit sector count at offset 15h as a provision for the future while still excluding it from the BPB. It is here thought that the three previously excluded fields became BPB members when the DOS kernel first started interpreting the 32-bit sector count.

The first known use of bpbHugeSectors by a DOS kernel is in a version 3.31 from Compaq. The DOS kernel treats the 32-bit bpbHugeSectors as superseding the 16-bit bpbSectors. That a BPB reaches as far as bpbHugeSectors is indicated by zero for bpbSectors.