Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Rikitav/Unified.Firmware/llms.txt

Use this file to discover all available pages before exploring further.

Hardware device path protocols describe the physical hardware components that make up the path from the processor to a storage device. They map directly to the Hardware Device Path type (0x01) defined in the UEFI specification, and each concrete class targets a specific sub-type within that category. You will typically encounter these nodes at the beginning of a complete device path — before messaging or media nodes — to identify which bus, controller, or PCI function is being addressed. Package: Unified.Firmware.DevicePathProtocols.Hardware Namespace: Unified.Firmware.BootService.Protocols

PciProtocol

Identifies a single PCI device by its Function and Device numbers on the PCI bus. This node appears in device paths for storage controllers, network adapters, and any other PCI endpoint that UEFI needs to locate.
[DefineDevicePathProtocol(DeviceProtocolType.Hardware, 1)]
public sealed class PciProtocol() : DevicePathProtocolBase(DeviceProtocolType.Hardware, 1)

Constructors

// Parameterless — properties set after construction
PciProtocol()

// Convenience constructor
PciProtocol(byte function, byte device)

Properties

PropertyTypeDescription
FunctionbytePCI function number of the device.
DevicebytePCI device number on the bus.

Serialization

GetSerializationDataLength() returns 2 (one byte each for Function and Device). The fields are written in the order Function, Device.

ToString

Pci(0x{Device:X}, 0x{Function:X})

Example

using Unified.Firmware.BootService.Protocols;

// Represents PCI device 0x1F, function 0x00 — a common SATA controller slot
var pci = new PciProtocol(function: 0x00, device: 0x1F);

Console.WriteLine(pci);
// Output: Pci(0x1F, 0x0)
Device and Function numbers can be read from the Windows Device Manager details pane or via lspci on Linux. On most x86 platforms, SATA controllers sit at device 0x1F.

MemoryMappedProtocol

Describes a device that is accessed through a fixed memory address range rather than a bus enumeration protocol. This includes memory-mapped I/O regions exposed by firmware or platform devices.
[DefineDevicePathProtocol(DeviceProtocolType.Hardware, 3)]
public sealed class MemoryMappedProtocol() : DevicePathProtocolBase(DeviceProtocolType.Hardware, 3)

Constructors

// Parameterless — properties set after construction
MemoryMappedProtocol()

Properties

PropertyTypeDescription
MemoryTypeuintEFI memory type identifier for the mapped region.
StartAddressulongFirst physical address of the memory-mapped region.
EndAddressulongLast physical address of the memory-mapped region (inclusive).

Serialization

GetSerializationDataLength() returns 20 bytes: 4 bytes for MemoryType, 8 bytes for StartAddress, and 8 bytes for EndAddress.

ToString

MemoryMapped(0x{MemoryType:X}, 0x{StartAddress:X}, 0x{EndAddress:X})

Example

using Unified.Firmware.BootService.Protocols;

var memMapped = new MemoryMappedProtocol
{
    MemoryType   = 11,                  // EfiMemoryMappedIO
    StartAddress = 0xFED40000UL,
    EndAddress   = 0xFED44000UL
};

Console.WriteLine(memMapped);
// Output: MemoryMapped(0xB, 0xFED40000, 0xFED44000)
The MemoryType field corresponds to the EFI_MEMORY_TYPE enumeration values defined in the UEFI specification (e.g., 11 = EfiMemoryMappedIO). Consult the UEFI 2.10 spec §7.2 for the full list of type codes.

ControllerProtocol

Identifies a specific controller by its controller number. This node is used when a single physical device exposes multiple logical controllers and a device path must pinpoint which one to use.
[DefineDevicePathProtocol(DeviceProtocolType.Hardware, 5)]
public sealed class ControllerProtocol() : DevicePathProtocolBase(DeviceProtocolType.Hardware, 5)

Constructors

// Parameterless — properties set after construction
ControllerProtocol()

// Convenience constructor
ControllerProtocol(uint controllerNumber)

Properties

PropertyTypeDescription
ControllerNumberuintZero-based controller index on the parent device.

Serialization

GetSerializationDataLength() returns 4 (a single uint).

ToString

Ctrl({ControllerNumber})

Example

using Unified.Firmware.BootService.Protocols;

// Reference the second controller (index 1) on a multi-port device
var ctrl = new ControllerProtocol(controllerNumber: 1);

Console.WriteLine(ctrl);
// Output: Ctrl(1)

VendorProtocol

Carries vendor-defined data in a hardware device path node, identified by a GUID. Use this when no standard hardware sub-type covers the required hardware abstraction. The VendorDefinedData payload is entirely opaque to the library and is round-tripped verbatim.
[DefineDevicePathProtocol(DeviceProtocolType.Hardware, 4)]
public sealed class VendorProtocol() : DevicePathProtocolBase(DeviceProtocolType.Hardware, 4)

Constructors

// Parameterless — properties set after construction
VendorProtocol()

Properties

PropertyTypeDescription
VendorGuidGuidVendor-assigned GUID that identifies the data format.
VendorDefinedDatabyte[]Variable-length opaque vendor payload. Defaults to an empty array.

Serialization

GetSerializationDataLength() returns 16 + VendorDefinedData.Length bytes. The GUID is written first as a 16-byte little-endian structure, followed by the raw vendor data.

ToString

Vendor({VendorGuid})

Example

using Unified.Firmware.BootService.Protocols;

var vendor = new VendorProtocol
{
    VendorGuid        = new Guid("a15a5af0-dab7-4b13-a3e9-7c4b9e1e5a5d"),
    VendorDefinedData = new byte[] { 0xDE, 0xAD, 0xBE, 0xEF }
};

Console.WriteLine(vendor);
// Output: Vendor(a15a5af0-dab7-4b13-a3e9-7c4b9e1e5a5d)
Ensure that VendorGuid is unique to your vendor and data format. Reusing a GUID registered by a different vendor may cause firmware to misinterpret the payload, leading to boot failures or silent data corruption.

Putting It Together

A typical device path for a PCI-attached NVMe drive begins with a PciProtocol node that identifies the storage controller, followed by further nodes for the NVMe namespace and media partition:
using Unified.Firmware.BootService.Protocols;

// Step 1 — Identify the PCI NVMe controller at device 0x1D, function 0x00
var pci = new PciProtocol(function: 0x00, device: 0x1D);

// Step 2 — Optionally drill into a specific controller instance
var ctrl = new ControllerProtocol(controllerNumber: 0);

// These nodes precede the Messaging and Media nodes that
// describe the NVMe namespace, partition, and file path.
DevicePathProtocolBase[] hardwarePath = [pci, ctrl];
Hardware nodes are almost never constructed in isolation. They form the leading segment of a full device path that also contains media nodes such as HardDriveProtocol and FilePathProtocol.

Build docs developers (and LLMs) love