Legacy PC Option ROMs: Header Validation, POST Discovery, and Initialization
Understand the legacy PC expansion-ROM header, BIOS scan ranges, far-call initialization, and compatibility limits before diagnosing a DOS boot path.
A legacy PC option ROM is firmware on an adapter that the system BIOS can discover and call during POST. It may initialize hardware, install a BIOS service, or make a storage device bootable before DOS is loaded. That lifecycle explains why a disk controller can appear to work in DOS only after its ROM has installed an INT 13h extension, or why a video adapter can provide INT 10h services before a DOS application starts.
The classic ROM format is a BIOS-era convention, not a guarantee for every PCI or UEFI device. This article covers the legacy PC/XT/AT-style expansion-ROM contract documented by IBM and Phoenix. It does not describe UEFI drivers, PCI device enumeration, or how to build and sign modern firmware.
Header, length, and checksum
For the documented legacy format, an expansion ROM begins with signature bytes 55h, AAh. The next byte gives the ROM length in 512-byte blocks. Byte offset 3 is the initialization entry point used by the BIOS’s far call. The BIOS validates the image checksum over the area indicated by the length field; the documented valid sum is zero modulo 256. A header that merely contains the signature is not enough to establish that an image is complete or valid.
The address and length arithmetic needs bounds. A diagnostic that inspects ROM contents after boot should first confirm that the candidate region is mapped and readable, then verify that the byte length is nonzero and that length multiplied by 512 stays inside the documented scan region without overflow. Do not trust a length byte to authorize a read past the upper-memory mapping. A checksum is a basic integrity check for this legacy format, not a cryptographic authenticity claim.
Some later PCI ROM images contain additional structures such as a PCIR data structure and can include multiple image types. The simple legacy header does not describe those extensions completely. If a tool parses PCI ROMs, use the PCI Firmware Specification for the image chain and code-type rules; the EDK II source is a useful implementation reference. Do not treat the first 512-byte length as a complete description of every modern option ROM container.
BIOS scan ranges are implementation-specific
The Phoenix CBIOS documentation describes POST searching designated video and general expansion-ROM ranges in 2 KiB increments. Its documented ranges include a video region beginning at C0000h and a general expansion region beginning at C8000h. IBM BIOS implementations and later compatibles may use different endpoints, exclusions, or scanning policies. A DOS utility should not infer that every byte from C0000h through EFFFFh is a valid extension ROM or that a device has been scanned merely because an address is inside that broad region.
ROM order can affect the environment because initialization code may install interrupt vectors or update BIOS data. A video ROM generally needs to be ready early enough to provide display services. A disk-controller ROM may add boot support or replace a BIOS path. The exact order and address rules belong to the firmware implementation and platform reference. When debugging a failed adapter, record the system BIOS, card ROM version, configured address, and whether the POST displayed or logged the initialization result.
Do not confuse an expansion ROM with a DOS device driver. A ROM runs during firmware initialization, before DOS’s CONFIG.SYS and AUTOEXEC.BAT processing. A SYS driver is loaded later by DOS and uses a DOS device-driver interface. A controller may need both: a ROM to extend BIOS boot services and a DOS driver for an operating system’s runtime behavior.
Initialization is a firmware call, not a DOS application
For the documented IBM/Phoenix contract, the BIOS calls the initialization routine at the ROM’s offset 3 using a far call. The routine executes in the system’s pre-boot environment and must follow the processor, memory, and stack conventions expected by that BIOS. It may initialize hardware, reserve or publish data, and install interrupt services. It must return control to the BIOS using the expected far-return convention so POST can continue.
An option ROM cannot assume that DOS is loaded. It must not call INT 21h for file I/O or depend on a DOS environment block. The BIOS may not yet have initialized every device that a runtime program would expect. The ROM must also avoid clobbering memory regions or vectors that the platform reserves. These constraints are specific to firmware code; ordinary DOS applications should use the interfaces that the ROM has installed rather than pretending they execute in the same initialization context.
For a bootable storage adapter, the ROM’s purpose may be to make the firmware’s boot process recognize a device or provide extended disk functions. A DOS application that later calls INT 13h may observe the combined BIOS-plus-ROM chain. Capture the vector before and after initialization in a controlled emulator if diagnosing which code supplies a service. Do not hook that vector again from DOS unless the application deliberately owns the chain and preserves the previous handler.
Failure diagnosis without executing unknown code
A post-boot inventory tool should inspect ROM bytes as data, not call them. Verify the signature, length, checksum, ROM address, and any documented header structures, then report the results. Executing an option ROM is a boot-time firmware action with system-wide effects; a diagnostic utility should not invoke an arbitrary ROM entry point as a test.
An absent ROM signature at an expected location can mean the card has no ROM, the ROM is disabled by a jumper or firmware option, the BIOS skipped that address, or the card uses a different mechanism. A signature with a failed checksum may be a corrupt image, a wrong boundary, or a mapping/read issue. A valid header but no visible adapter function can result from ROM initialization failure, resource conflict, unsupported system architecture, or a later handler replacing the service.
Avoid rewriting a card ROM from DOS merely because a header check fails. Firmware updates can render hardware unbootable if the wrong image or address is used. Preserve a read-only image and hardware identity, verify the vendor’s procedure, and use a documented recovery method before any write operation. This is operational preservation advice, not a claim that a checksum verifies vendor provenance.
Compatibility with DOS and FreeDOS
FreeDOS runs after system firmware has completed POST and transferred control into the boot path. A DOS program normally consumes BIOS services established by option ROMs; it does not participate in the ROM scan itself. This distinction helps classify failures: if an adapter cannot boot, the problem may precede FreeDOS; if the machine boots but DOS cannot access the adapter at runtime, the missing piece may be a DOS driver or a BIOS compatibility limitation.
Some emulators can enable or disable particular ROMs, map them at different addresses, or emulate a device without exposing a physical ROM image. In those environments, the guest’s observed service may not correspond to a byte array accessible from DOS. Record emulator version and option settings. Do not treat a successful boot in one VM as proof that a real card’s ROM initialized correctly.
The legacy header also does not guarantee that a ROM is PC-compatible just because it starts with 55 AAh. The platform BIOS must search the region, accept the size and checksum, and call an entry that understands the machine’s interface. MCA and later PCI devices may use bus-specific resource and initialization rules. Match the ROM documentation to the adapter architecture.
Acceptance checks for a ROM inventory tool
Test the parser against a known IBM/Phoenix-compatible ROM image and synthetic malformed data. Include a missing signature, zero length, a length that crosses the mapped boundary, bad checksum, and a valid header with unknown trailing bytes. Confirm that all cases are reported without calling the initialization entry point. Preserve the original bytes and computed checksum so the result can be independently reproduced.
On real hardware, compare the tool’s read-only report with the card’s label and the BIOS setup/POST output. If a ROM is shadowed into RAM, document whether the tool read the physical ROM, a shadow copy, or an emulator mapping. Keep the source address and read method with the checksum; the same byte sequence at a different mapping does not prove how POST handled it.
For a boot-path investigation, capture the BIOS version, option-ROM address, signature, size, checksum, POST message, boot device selected, and the BIOS services present after boot. Separate those observations from DOS driver load messages. That gives maintainers enough evidence to decide whether the fault belongs to firmware discovery, ROM initialization, or the later FreeDOS runtime layer.
The key boundary is timing and ownership: firmware discovers and initializes option ROMs during POST; DOS later uses the services and drivers that exist. A sound diagnosis reads the legacy header carefully, respects the BIOS-specific scan rules, and never executes an unknown ROM simply to see what happens.
Related:
- FreeDOS SYS: Install the Kernel and Boot Sector Without Repartitioning
- Reading Legacy PnP BIOS Device Nodes from a DOS Utility
Sources: