Skip to content
FreeDOSDeep Dive Published Updated 7 min readViews unavailable

Reading Legacy PnP BIOS Device Nodes from a DOS Utility

Inspect the legacy Plug and Play BIOS interface, system-device nodes, resource descriptors, and the limits of firmware inventory on DOS.

Legacy Plug and Play on a DOS machine is not one feature. ISA Plug and Play devices have a hardware configuration protocol; the Plug and Play BIOS specification describes a firmware interface for system software; and DOS drivers still have to claim and operate their hardware. A utility that treats these layers as interchangeable can report a device that it cannot drive, or mistake a firmware’s boot-time resource assignment for a guarantee that remains valid after another component changes the machine.

The PnP BIOS specification was published jointly by Compaq, Phoenix, and Intel as version 1.0A in 1994. It describes an installation structure and a far-call entry point through which software can query and, for some functions, manage system device nodes. The interface is a historical firmware contract. A present-day FreeDOS installation may run on firmware without it, and its absence does not mean that the machine has no PCI or ISA devices.

Discover the interface before calling it

The specification defines a Plug and Play BIOS installation-check structure. System software locates and validates the structure before using the entry point: it checks the signature, structure length and checksum, and validates the reported entry-point information. Do not scan arbitrary memory and call a near-looking pointer just because a byte sequence resembles $PnP. Real-mode segment:offset values are not protected pointers, so malformed firmware data can crash the machine or corrupt memory.

The installation structure carries information needed to make calls in the execution mode supported by the BIOS, including the real-mode entry point and mode-specific data. A 16-bit DOS utility should use only the real-mode interface fields whose interpretation is defined by the specification. Protected-mode entry points are not directly callable from a plain real-mode program; a DPMI client requires a host-mediated transition and correct selector setup.

Treat the scan as a bounded parser. Check that every field lies within the declared structure, that the checksum is valid, and that the entry segment:offset is plausible for the documented mapping. If validation fails, stop with “PnP BIOS data invalid” rather than trying another guessed address. Keep diagnostics read-only unless the program is explicitly intended to change firmware configuration and has a tested recovery plan.

System device nodes are firmware inventory

The PnP BIOS API includes a function to get the number of system device nodes and the largest node size, followed by a function to retrieve a requested node. The specification’s wording is important: these nodes represent system-board devices that the BIOS returns. They are not necessarily a complete list of every expansion card, every logical function, or every device currently managed by a DOS driver.

Allocate a buffer based on the reported maximum size, but validate the returned length before parsing it. A node contains a handle and a sequence of resource descriptors. Descriptors can encode possible resource configurations and the current or boot-time resource assignment. Their tagged, variable-length structure means a parser must advance by each descriptor’s defined size, check remaining bytes before reading, and reject unknown or truncated forms safely.

Resource data can include I/O ranges, memory ranges, IRQs, and DMA channels. A descriptor says what firmware describes for that node; it does not grant the caller ownership. Do not reprogram the device merely because an IRQ number appears in the node. Before a DOS driver claims a range, compare it with other drivers, firmware settings, jumpers, and machine-specific documentation. A node snapshot is evidence for diagnostics, not a reservation primitive.

Query before mutation

The safer use case is inventory: identify that firmware advertises a built-in controller, record the node handle and resource descriptors, and use the information to guide a human or a driver selection routine. Functions that set a node or write extended system configuration data can alter persistent or live platform configuration. They are not substitutes for a motherboard setup utility, and a bad write may make hardware unavailable at the next boot.

Keep these boundaries in code:

validate installation structure
if absent or invalid: report unsupported/invalid firmware data
query node count and maximum node size
for each node handle:
    fetch into a bounded buffer
    validate returned node length and descriptor lengths
    record identifiers/resources without changing them

This is deliberately pseudocode, not a callable assembly listing. The BIOS entry convention has mode, calling-convention, and selector details that must match the PnP BIOS specification and the program’s memory model. A copied snippet that happens to work on one compiler can corrupt the stack or pass the wrong far pointer on another.

When presenting data, distinguish “BIOS node exists,” “device responded,” and “DOS driver loaded.” The first is firmware’s description; the second requires a device-level probe performed by the appropriate driver; the third is a software configuration fact. A stale or incomplete node table can coexist with a working device, especially when firmware or a memory manager owns device initialization.

Keep a raw evidence record when the node table is used to troubleshoot a boot. Store the BIOS installation-structure revision and declared size, the function/status returned for each node, the node handle, and the exact descriptor bytes that were accepted. That record makes it possible to compare two firmware versions without treating a parser’s formatted summary as ground truth. Do not write the captured bytes back into ESCD or a BIOS setup area: the PnP BIOS API and the platform’s persistent configuration format are related but not identical contracts.

For portability, parse only resource-tag types defined by the specification revision you implement and preserve unknown descriptors as opaque data if the enclosing length is valid. Reject malformed lengths before arithmetic can wrap a 16-bit offset. A hostile or buggy firmware structure is unusual, but the parser still runs in a memory model where one bad length can overwrite the application or resident DOS structures. Unit tests with truncated and maximal-length descriptors are inexpensive protection.

Why enumeration can fail on a working system

PnP BIOS services are optional and old. Many systems expose ISA Plug and Play or PCI hardware through other mechanisms, while omitting the legacy PnP BIOS API. Some BIOS implementations have bugs in rarely used node functions. A virtual machine may synthesize a minimal firmware interface or none at all. A query can fail because the function is unsupported, the handle is invalid, or the BIOS reports an error; do not collapse every condition into “hardware absent.”

There is also a timing issue: a node list may reflect BIOS configuration at boot rather than the state after a DOS driver or configuration utility has changed resources. If software caches the result, record when it was read and avoid assuming it remains authoritative. Do not call mutating node operations while a driver is active unless both the firmware contract and driver documentation explicitly coordinate that operation.

A disciplined implementation and test plan

Separate detection, parsing, and reporting. Detection validates the installation structure and records the selected real-mode entry. Parsing consumes a length-bounded node buffer and cannot issue BIOS calls. Reporting labels every resource as firmware-reported, not reserved. This separation makes it possible to unit-test malformed descriptor sequences without invoking firmware.

Test with a BIOS that implements the API, a system where the signature is absent, and a deliberately malformed test buffer. Include a node count of zero, a maximum-size boundary, a short node, an unknown descriptor type, and a BIOS error on one handle. On real hardware, capture a pre-change setup record and avoid testing set-node or ESCD write functions unless you have a documented restoration method.

For normal FreeDOS applications, prefer existing DOS device interfaces and vendor drivers over direct PnP BIOS calls. Use the API when building a diagnostic or installer that can tolerate it being absent. This keeps the program honest about its role: it reads legacy firmware configuration; it does not implement Plug and Play policy, allocate resources, or provide the hardware driver.

Related:

Sources:

Comments