EFI(4)

πŸ“¦ in nixpkgs unstable

πŸ’– EFI(4) πŸ’–

okay so this is the efi page from the Kernel Interfaces Manual β€” yes, that manual β€” and honestly? it's kind of a baddie. it's all about the Unified Extensible Firmware Interface, aka the thing your firmware speaks before your kernel even wakes up. let's get into it, bestie 🫢


✨ NAME ✨

efi β€” Unified Extensible Firmware Interface. that's the whole name, no notes πŸ’…


✨ SYNOPSIS ✨

so the way you attach this thing depends on your arch, and it's giving "pick your fighter":

# amd64
efi* at bios?

# arm64
efi* at fdt?

amd64 rides on bios?, arm64 rides on fdt?. that's it, that's the config πŸŽ€


πŸ¦‹ DESCRIPTION πŸ¦‹

the efi driver is literally the support system for EFI runtime services β€” the stuff your UEFI firmware implementations keep offering you after boot. no cap.

what does it actually do? a few iconic things:

  • it can read and write the Real Time Clock ⏰
  • it gives userland applications ioctl(2) access to the System Resource Table (the ESRT, iykyk)
  • and it lets you read and write variables πŸ”₯

so yeah. clock stuff, table stuff, variable stuff. main character energy for a driver tbh.


πŸ’… IOCTLS πŸ’…

efi supports the following ioctl(2) commands, and you can get at them through <dev/efi/efi.h> and <dev/efi/efiio.h>. three guesses who your new best friends are: those two headers ✨

  • EFIIOC_GET_TABLE with a struct efi_get_table_ioc * β€” reads a table. the struct:
struct efi_get_table_ioc {
        void *buf;          /* Pointer to userspace buffer */
        struct uuid uuid;   /* UUID to look up */
        size_t table_len;   /* Table size */
        size_t buf_len;     /* Size of the buffer */
};
  • EFIIOC_VAR_GET with a struct efi_var_ioc * β€” reads a variable. struct time:
struct efi_var_ioc {
        uint16_t *name;     /* User pointer to name, in UCS2 chars */
        size_t namesize;    /* Number of *bytes* in the name
                               including terminator */
        struct uuid vendor; /* Vendor's UUID for variable */
        uint32_t attrib;    /* Attributes */
        void *data;         /* User pointer to value */
        size_t datasize;    /* Number of *bytes* in the value */
};
  • EFIIOC_VAR_NEXT with a struct efi_var_ioc * β€” enumerates all the variables. the rules: the first command has to use the empty name, and every one after that has to denote the previous variable's name and UUID. don't skip steps, bestie, it's a chain πŸ‘‘
  • EFIIOC_VAR_SET with a struct efi_var_ioc * β€” writes a variable. and lowkey the wild part: delete it if datasize is zero πŸ’€ yeah, zero-length means bye-bye.
also please note namesize and datasize are in bytes, not chars, not vibes. the name one includes the terminator too. get that wrong and it's not giving slay, it's giving segfault.

πŸ“ FILES πŸ“

  • /dev/efi β€” the device node, the doorway, the moment 🌈

πŸ‘‘ SEE ALSO πŸ‘‘


🌸 HISTORY 🌸

the efi device driver first appeared for arm64 in OpenBSD 6.3 β€” a little baby driver, we love her origin story 🧚

then support for amd64, the ESRT and EFI variables appeared in OpenBSD 7.3. glow-up era, honestly ⭐


πŸ’œ AUTHORS πŸ’œ

  • the efi driver was written by Mark Kettenis <kettenis@openbsd.org> πŸŽ€
  • support for the ESRT and EFI variables is heavily based on work done by Sergii Dmytruk <sergii.dmytruk@3meb.com> 🫢

and that's the page!! this version of EFI(4) is from the Debian build of the manual, dated May 5, 2024 β€” so if you're citing it in your group chat, that's your receipt πŸ”₯ ily, go read ioctl(2) next πŸ’–

πŸ“¦ where this page comes from
  • nixpkgs unstable: cvs-export
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms