An Option ROM for the PC platform (i.e. the IBM PC and derived successor computer systems) is a piece of firmware that resides in ROM on an expansion card (or stored along with the main system BIOS), which gets executed to initialize the device and (optionally) add support for the device to the BIOS. In its usual use, it is essentially a driver that interfaces between the BIOS API and hardware. Technically, an option ROM is firmware that is executed by the BIOS after POST (the testing and initialization of basic system hardware) and before the BIOS boot process, gaining complete control of the system and being generally unrestricted in what it can do. The BIOS relies on each option ROM to return control to the BIOS so that it can either call the next option ROM or commence the boot process. For this reason, it is possible (but not usual) for an option ROM to keep control and preempt the BIOS boot process. The BIOS (at least as originally designed by IBM) generally scans for and initializes (by executing) option ROMs in ascending address order at 2 KB address intervals within two different address ranges above address C0000h in the conventional (20-bit) memory address space; later systems may also scan additional address ranges in the 24-bit or 32-bit extended address space.
Option ROMs are necessary to enable non-Plug and Play peripheral devices to boot and to extend the BIOS to provide support for any non-Plug and Play peripheral device in the same way that standard and motherboard-integrated peripherals are supported. Option ROMs are also used to extend the BIOS or to add other firmware services to the BIOS. In principle, an option ROM could provide any sort of firmware extension, such as a library of video graphics subroutines, or a set of PCM audio processing services, and cause it to be installed into the system RAM and optionally the CPU interrupt system before boot time.
A common option ROM is the video BIOS which gets loaded very early on in the boot process and hooks INT 10h so that output from the power-on self-test (POST) can be displayed. The video BIOS is almost always located in the memory segment beginning at C0000h
, the start of the memory area reserved for option ROMs; this is because when the motherboard has a built-in VGA controller, the option ROM will reside in the BIOS – the BIOS knows where it is and shadows it into RAM at a fixed time. Other ROMs can be located from segments C8000h
all the way up to F4000h
in early PCs.[1] The final search address was limited to segment DFFFFh
[2] or EFFFFh
[3] in modern products. The BIOS Boot Specification requires that option ROMs be aligned to 2 kB boundaries (e.g. segments C8000h, C8800h, C9000h, C9800h
, etc.). The first two bytes of the ROM must be 55 AA
.[4] The third byte indicates the ROM size in 512-bytes blocks (e.g. 20h
for 16kB ROM). And the fourth byte is where the BIOS begins execution of the option ROM to initialize it before the system boots.Often this initialization is done by a 3 byte jump instruction starting with hexadecimal value E9
.[5]
Prior to the development and ubiquitous adoption of the Plug and Play BIOS standard, an add-on device such as a hard disk controller or a network adapter card (NIC) was generally required to include an option ROM in order to be bootable, as the motherboard BIOS did not include any support for the device and so could not incorporate it into the BIOS's boot protocol. Such an option ROM would hook INT 19h, the BIOS boot interrupt, to preempt the BIOS boot loader and substitute their own boot loader. The boot loader on the option ROM would attempt to boot from a disk, network, or other boot program source attached to or installed on the adapter card; if that boot attempt failed, it would pass control to the previous boot loader (to which INT 19h pointed before the option ROM hooked it), allowing the system to boot from another device as a fallback strategy. Some adapters cards, such as certain SCSI adapters (e.g. some made by Adaptec), were available in versions that differed only in the presence or absence of the option ROM to enable booting from attached SCSI devices. As a result of the option ROM scanning protocol, the highest-addressed option ROM is the last one to be initialized and so the last one to hook any interrupts and the first one in those interrupt service routine (ISR) chains; thus the addresses of the option ROMs completely determine the boot priority between adapter cards that are enabled for booting, and the boot devices supported by the motherboard BIOS collectively have lowest priority, i.e. the system will attempt to boot from them only after attempting to boot from all boot-enabled adapter cards.
The BIOS Boot Specification (BBS) was developed by a consortium comprising Compaq, Intel and Phoenix Technologies to standardize the initialization sequence of Plug and Play (PnP) BIOS and Option ROMs. The standard presents the notion of a Boot Connection Vector (BCV) table and BCV priority. The core principles of the standard make behaviour more defined and debuggable and gives BIOS manufacturers room to further dynamise boot device selection for the user, beyond the suggestions of the standard.The beginning of the PnP Expansion header is marked by the 4 byte ASCII signature $PnP
anda pointer to this is stored at offset +1Ah as a 2 byte little endian value.[6]
After the basic POST checks are complete, the BBS specifies that the BIOS will detect and shadow all option ROMs that reside in the BIOS into the aforementioned region and it will traverse the PCI configuration space, filling in XROMBARs and copying the expansion card option ROMs from MMIO space to the region. The BIOS then scans the region, and if the option ROM has a PnP Expansion header, it does a far call to offset +03h in the option ROM header to initialize it. It then rescans the region after all the PnP option ROMs have been initialized (because, as appendix E states, the option ROM initialization routine may have chained more PnP expansion headers for individual disks the device owns). It adds the BCV pointer (if present) in the PnP Expansion headers it finds the BCV Table or the BEV pointer (if present) to the IPL priority table. The BCV entries in the BCV table are then called according to priority settable in NVRAM. The BCV table is full of BCV function pointers but has a fixed entry representing legacy option ROMs which is a pointer to a BIOS routine which calls +03h in all the remaining option ROMs that don't have a PnP Expansion header. The BCV function initializes the INT 13h and INT 19h hooks, which the BBS stipulates must not be done in the initialization routine at +03h. If a device has no PnP Expansion header, it may perform any hook in the routine at +03h, as it is a legacy card.
In the initial initialization routine, as the Option ROM points to a PCI data structure (not the same as the configuration space), the option ROM code knows the device and vendor ID is at a fixed offset from RIP. The beginning of this structure is marked by the 4 byte ASCII signature PCIR
anda pointer to this is stored at offset +18h as a 2 byte little endian value.[6] This allows it to scan the PCI configuration space to find the correct device and BARs it needs to use. To prevent this scan, and in case of two identical cards in the system, the BIOS passes the PFA (bus/device/function) to the initialization routine in AX, and the card select number (CSN) for ISA option ROMs is passed in BX. It can then interact with the device using PMIO / MMIO to see how many disks it has and which ones are bootable by reading the MBR. The BIOS will have already combed the configuration space, allocated the BARs and filled in the ACPI table prior to the initialization routine call, so the option ROM would use the addresses allocated to its BARs. The BCV, however, hooks interrupt routines which interact with the device which are adjusted based on a base MMIO address location, disk information ascertained in the option ROM initialization routine and the current disk number in the BDA.
The BIOS INT 19h procedure then uses the IPL table priority in NVRAM to decide whether to call an entry containing a boot handler which will read the MBR of 00h (floppy disk BAID; the first device in the BCV table to register disk 00h), an entry containing a boot handler which will read the MBR of 80h (the hard drive BAID; the first device in the BCV Table to register disk 80h) or one of the BEV entries in the table. A device only has a BEV or a BCV if it is a bootable device.
A SCSI controller card may hook INT 13h which is responsible for providing disk services. It will do so in its BCV if it is a PnP card. Once it has done this, any subsequent calls to INT 13h will be "caught" by the SCSI option ROM (or "SCSI BIOS"), allowing it to respond for disks that may exist on the SCSI bus. Before it had hooked the interrupt there may have been no disks on the system, but by intercepting the interrupt and altering the values returned, the SCSI BIOS can make all the disks on the SCSI bus visible to the system.
In this particular case, the BIOS itself may call INT 13h to provide a list of possible boot devices to the user, and because the SCSI BIOS has hooked the interrupt the user will be able to choose not only which standard system devices to boot from, but also which SCSI disks as well. This is because, as suggested in Appendix D of the Boot BIOS Specification, the BIOS could populate the IPL table with device and vendor information from INT 13h calls to the different disks, paired with the Hard Disk Number (80h, 81h ...), to allow any hard disk device to be booted from, rather than just the first disk of the first controller to hook INT 13h (the highest priority item in the BCV table), referred to as a BIOS Aware IPL Device (BAID) in the specification.
Multiple controllers can hook INT 13h at once. For instance, after the SCSI controller, an AHCI controller can also hook INT 13h by putting a call to the previous handler, which was stored in the IDT at entry 13h by the SCSI controller, at the end of its own handler, before it puts the address of its own handler into the IDT at entry 13h. The first controller to hook INT 13h will see that 0 disks have been installed by checking the byte at 0040:0075
, which resides in the BIOS Data Area (BDA), and if it has 4 disks to enumerate, it will assign the range of disk numbers 80h–83h and store '4' in the BDA. If the second controller to hook INT 13h has 2 disks, it will read '4' from the BDA, assign the disk numbers 84h and 85h, and store '6' in place of the '4'. Now if INT 13h is called with DL = 83h, then the handler of the second controller, which did not assign disk number 83h, will relay the call to the previous handler; that handler, which did assign disk number 83h, will handle the call itself. With any number of controllers' ISRs hooked into INT 13h, the ISRs will each pass control to the next one until the one that assigned the specified drive number recognizes the number, handles the call, and returns from the interrupt.
Another common option ROM is a network boot ROM. The option ROM contains the program required to download the boot code. The original IBM Personal Computer ROMs hooked INT 18H (originally to invoke Cassette BASIC) and INT 19H, as these two interrupts were used for the boot process. INT 19h is called to initiate the boot process, and INT 18h was called to start Cassette BASIC from ROM when the boot process found that none of the possible boot devices was bootable. Originally, by hooking INT 18h, the network adapter ROM would try to boot from the network when all other boot devices (floppy drives, hard drives, etc.) had failed. By hooking INT 19H, the network adapter ROM would attempt to boot from the network before any other devices. The BBS specifies that the NIC option ROM does not hook INT 19h, but instead the BIOS 19h handler should call the BEV, which will then download the boot code.
The Video BIOS provides some basic display services for BIOS and operating systems, for example INT 10H (Legacy BIOS), VBE (Legacy BIOS) and UEFI GOP. The original IBM PC BIOS included integrated support for the IBM CGA and MDA video adapters (and did not support option ROMs at all), so those video cards had no option ROMs. The CGA and MDA support in the BIOS proper was maintained through the IBM PC XT and PC AT product lines (which did support option ROMs), so that those cards worked (with full BIOS support) in those machines. The first PC video adapter card that had an option ROM was the IBM EGA, introduced in 1984 with the IBM PC AT. (The Hercules Graphics Card had no option ROM and no BIOS support except for its MDA-compatible features, for which it relied in the IBM-supplied MDA support in the main BIOS.) Most subsequent PC video adapters were supported by option ROMs, although VGA and MCGA integrated onto PS/2 motherboards may have used integrated BIOS support. Once integrated Super VGAs (SVGAs), integrated on clone PC motherboards, were being provided by separate companies than the systems themselves, it became common for the SVGA vendor-provided video BIOS to be included as a separate option ROM module on the same BIOS chip as the main system BIOS (provided by a third separate company).
The PCI spec allows multiple option ROM images on the same device. These option ROMs could be Legacy x86 & UEFI. If the Option ROM format is set to "UEFI Compatible" in the UEFI Setup, the Driver Execution Environment (DXE) stage will load the newer UEFI Option ROM if one is present and the legacy Option ROM if one is not. UEFI can use legacy option ROMs when a Compatibility Support Module (CSM) is enabled. Note that when Secure Boot is enabled, execution of the Compatibility Support Module and legacy option ROMs is prohibited because legacy firmware drivers do not support authentication, which is a security hole.[7]