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
| Property | Type | Description |
|---|
Function | byte | PCI function number of the device. |
Device | byte | PCI 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
| Property | Type | Description |
|---|
MemoryType | uint | EFI memory type identifier for the mapped region. |
StartAddress | ulong | First physical address of the memory-mapped region. |
EndAddress | ulong | Last 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
| Property | Type | Description |
|---|
ControllerNumber | uint | Zero-based controller index on the parent device. |
Serialization
GetSerializationDataLength() returns 4 (a single uint).
ToString
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
| Property | Type | Description |
|---|
VendorGuid | Guid | Vendor-assigned GUID that identifies the data format. |
VendorDefinedData | byte[] | 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
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.