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.

UEFI stores boot entries as individual NVRAM variables named Boot0000 through BootFFFF. Each one encodes a human-readable description, a packed device path list that tells the firmware where to find the boot image, optional binary data passed to the loaded image, and attribute flags. A separate variable — BootOrder — holds the priority-ordered array of indices the firmware walks when deciding what to boot. FirmwareBootService is the static class that lets you read and manipulate all of this from managed C# code.

Boot Order Properties

LoadOrder

Gets or sets the full BootOrder NVRAM variable as a BootOptionIndex[]. Changing this array rewrites the variable immediately.

CurrentLoadOptionIndex

Returns the BootOptionIndex of the entry that launched the running OS (backed by BootCurrent). Read-only.

NextLoadOptionIndex

Set-only. Writes to BootNext, which overrides the boot order for exactly one reboot, then is cleared by the firmware.
// Print the current boot order
BootOptionIndex[] order = FirmwareBootService.LoadOrder;
Console.WriteLine("Boot order: " + string.Join(", ", order));

// Move entry 0x0002 to the front
var newOrder = new[] { (BootOptionIndex)0x0002 }
    .Concat(order.Where(x => x != 0x0002))
    .ToArray();
FirmwareBootService.LoadOrder = newOrder;

// One-time override: boot entry 0x0003 on the next reboot only
FirmwareBootService.NextLoadOptionIndex = 0x0003;

// Which entry booted the current OS?
Console.WriteLine($"Booted from: Boot{FirmwareBootService.CurrentLoadOptionIndex:X4}");

CRUD Operations

Reading a Single Entry

FirmwareBootOption ReadLoadOption(BootOptionIndex bootOptionIndex);
T ReadLoadOption<T>(BootOptionIndex bootOptionIndex) where T : LoadOptionBase, new();
EFI_LOAD_OPTION ReadRawLoadOption(BootOptionIndex bootOptionIndex);
ReadLoadOption deserializes the Boot#### variable into a FirmwareBootOption. Use the generic overload when you have a custom LoadOptionBase subclass. Use ReadRawLoadOption when you need the native EFI_LOAD_OPTION struct without any managed interpretation.
// Read the entry that launched the current OS
BootOptionIndex current = FirmwareBootService.CurrentLoadOptionIndex;
FirmwareBootOption option = FirmwareBootService.ReadLoadOption(current);

Console.WriteLine($"Description : {option.Description}");
Console.WriteLine($"Attributes  : {option.Attributes}");
Console.WriteLine($"Protocol count: {option.Protocols.Length}");

Enumerating All Entries

IEnumerable<FirmwareBootOption> EnumerateBootOptions();
Walks BootOrder in order and yields a deserialized FirmwareBootOption for each entry. The sequence respects the current boot priority order.
foreach (FirmwareBootOption entry in FirmwareBootService.EnumerateBootOptions())
{
    Console.WriteLine($"Boot{entry.Description}");
    foreach (var proto in entry.Protocols)
        Console.WriteLine($"  {proto}");
}

Creating a New Entry

BootOptionIndex CreateLoadOption(LoadOptionBase loadOption, bool addFirst);
Scans BootOrder for the first unused index (starting at Boot0000), writes the serialized option to that slot, appends or prepends the index in BootOrder, and returns the newly assigned BootOptionIndex. Pass addFirst: true to make it the highest-priority entry.
var newOption = new FirmwareBootOption(
    LoadOptionAttributes.ACTIVE | LoadOptionAttributes.CATEGORY_BOOT,
    "My Custom OS",
    protocols: new DevicePathProtocolBase[]
    {
        new HardDriveProtocol(partitionGuid),
        new FilePathProtocol(@"EFI\myos\bootx64.efi")
    },
    optionalData: Array.Empty<byte>());

BootOptionIndex idx = FirmwareBootService.CreateLoadOption(newOption, addFirst: true);
Console.WriteLine($"Created Boot{idx:X4}");

Updating an Existing Entry

void UpdateLoadOption(LoadOptionBase loadOption, BootOptionIndex bootOptionIndex);
Serializes loadOption and overwrites the Boot#### variable at bootOptionIndex. The boot order is not changed.
var updated = new FirmwareBootOption(
    LoadOptionAttributes.ACTIVE | LoadOptionAttributes.CATEGORY_BOOT,
    "Renamed OS Entry",
    existingOption.Protocols,
    existingOption.OptionalData);

FirmwareBootService.UpdateLoadOption(updated, targetIndex);

Editing with a Callback

void EditLoadOption(BootOptionIndex bootOptionIndex, Action<FirmwareBootOption> updateAction);
Performs a read-modify-write cycle in one call. The callback receives the deserialized FirmwareBootOption; mutate it and EditLoadOption writes it back automatically.
FirmwareBootService.EditLoadOption(targetIndex, option =>
{
    option.Description = "Updated Description";
    option.Attributes |= LoadOptionAttributes.ACTIVE;
});

Deleting an Entry

void DeleteLoadOption(BootOptionIndex loadOptionIndex);
Writes a null/zero-byte payload to the Boot#### variable (erasing it from NVRAM) and removes the index from BootOrder.
FirmwareBootService.DeleteLoadOption(obsoleteIndex);
Console.WriteLine($"Boot{obsoleteIndex:X4} deleted.");

FirmwareBootOption Model

FirmwareBootOption is the concrete LoadOptionBase implementation used for all standard boot entries.
PropertyTypeDescription
AttributesLoadOptionAttributesFlags controlling entry visibility and category (ACTIVE, HIDDEN, CATEGORY_BOOT, …)
DescriptionstringHuman-readable label shown in the firmware boot menu
ProtocolsDevicePathProtocolBase[]Packed device path sequence that locates the boot image
OptionalDatabyte[]Arbitrary binary data passed to the loaded EFI image as load options
var option = new FirmwareBootOption(
    LoadOptionAttributes.ACTIVE | LoadOptionAttributes.CATEGORY_BOOT,
    "Ubuntu 24.04",
    new DevicePathProtocolBase[]
    {
        new HardDriveProtocol(espPartitionGuid),
        new FilePathProtocol(@"EFI\ubuntu\grubx64.efi")
    },
    optionalData: Array.Empty<byte>());

BootOptionIndex

BootOptionIndex is a thin ushort wrapper that formats as the canonical Boot#### variable name (zero-padded, upper-case hex). It is implicitly convertible from and to ushort.
BootOptionIndex idx = 0x000A;
Console.WriteLine(idx.ToString()); // → "Boot000A"

// Implicit conversions
ushort raw = idx;          // 10
BootOptionIndex back = 10; // Boot000A
1

Check availability

Call FirmwareInterface.Available before any boot service operation to confirm the system was started in UEFI mode.
2

Read current entries

Use EnumerateBootOptions() or ReadLoadOption() to inspect what is already in NVRAM.
3

Modify or create

Use CreateLoadOption, UpdateLoadOption, or EditLoadOption to make changes.
4

Verify the boot order

Check LoadOrder afterwards to confirm the index appears at the correct position.
All write operations (CreateLoadOption, UpdateLoadOption, EditLoadOption, DeleteLoadOption) immediately commit changes to NVRAM flash. There is no transaction or undo mechanism — changes survive every subsequent reboot until explicitly reverted. Test with care on production machines.
For step-by-step walkthroughs, see the related guides:

Build docs developers (and LLMs) love