serexp/nvwrite
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
███▄▄▄▄ ▄█ █▄ ▄█ █▄ ▄████████ ▄█ ███ ▄████████
███▀▀▀██▄ ███ ███ ███ ███ ███ ███ ███ ▀█████████▄ ███ ███
███ ███ ███ ███ ███ ███ ███ ███ ███▌ ▀███▀▀██ ███ █▀
███ ███ ███ ███ ███ ███ ▄███▄▄▄▄██▀ ███▌ ███ ▀ ▄███▄▄▄
███ ███ ███ ███ ███ ███ ▀▀███▀▀▀▀▀ ███▌ ███ ▀▀███▀▀▀
███ ███ ███ ███ ███ ███ ▀███████████ ███ ███ ███ █▄
███ ███ ███ ███ ███ ▄█▄ ███ ███ ███ ███ ███ ███ ███
▀█ █▀ ▀██████▀ ▀███▀███▀ ███ ███ █▀ ▄████▀ ██████████
███ ███
A Serexp & FGL Production..................................................
Cross-platform NVRAM (UEFI) variable access library.
===================================================================
THE WHAT
===================================================================
nvwrite is a lightweight utility to read, write, and delete NVRAM variables
from user space.
- Primary target: Linux (via sysfs efivars)
- Secondary: Windows (via GetFirmwareEnvironmentVariable)
It is designed for low-level system tools and embedded-like
environments where full CRT may not be available. On Linux, it only relies
on these functions:
close, closedir, open, opendir, read, readdir, unlink, write
These can eventually be swapped for their syscalls equivalent, but it
was not done. On Windows, we rely on {Set/Get}FirmwareEnvironmentVariable.
===================================================================
THE HOW
===================================================================
- Minimal, self-contained C API
- Symmetric error codes across platforms
- Optional debug logging (enabled with debug builds)
- Supports reading/writing raw binary UEFI variable data
===================================================================
THE WHAT. AGAIN.
===================================================================
---
/* nvwrite.h */
#define nvwrite_OK 0
#define nvwrite_ERR_INVALID -1
#define nvwrite_ERR_NOTFOUND -2
#define nvwrite_ERR_ACCESS -3
#define nvwrite_ERR_BUFFER -4
#define nvwrite_ERR_PLATFORM -5
int nvwrite_read(const char *name, void *buffer, uint32_t *size);
int nvwrite_write(const char *name, const void *data, uint32_t size);
int nvwrite_delete(const char *name);
int nvwrite_list(void (*callback)(const char *name, void *ctx), void *ctx);
---
nvwrite_read: Read an NVRAM variable into buffer. On input, *size = buffer capacity;
on output, *size = bytes read.
nvwrite_write: Write data (size bytes) to an NVRAM variable.
nvwrite_delete: Delete the specified variable.
nvwrite_list: Enumerate all variable names (Linux only; Windows returns
nvwrite_ERR_PLATFORM). Calls callback(name, ctx) for each.
All functions return 0 (nvwrite_OK) on success, or a negative error code.
===================================================================
Platform=specific stuff aka why we can't have nice things
===================================================================
---
Linux
Uses /sys/firmware/efi/efivars (requires efivarfs mounted, usually done by
systemd or kernel).
Requires root privileges (or CAP_SYS_ADMIN) for write/delete.
Variable names appear as "VariableName-GUID". You must pass the full name as
shown in the filesystem.
---
Windows
Uses {Set/Get}FirmwareEnvironmentVariableA.
The GUID is hard‑coded to {00000000-0000-0000-0000-000000000000}
(EFI_GLOBAL_VARIABLE namespace per the UEFI spec).
For vendor‑specific variables, you would need to extend the API.
Write/delete requires SeSystemEnvironmentPrivilege, not available to
normal users by default.
nvwrite_list is not implemented on Windows. For now!
===================================================================
BUILDING
===================================================================
Release (freestanding, no libc)
make
The object file can be linked into your project without standard libraries.
Debug (with libc, printf logging)
make debug
===================================================================
HOW 2 USE
===================================================================
Check the cli.c code.
Error Codes
nvwrite_OK (0): Success
nvwrite_ERR_INVALID: Null pointer or zero size
nvwrite_ERR_NOTFOUND: Variable does not exist
nvwrite_ERR_ACCESS: Permission denied, or kernel/OS error
nvwrite_ERR_BUFFER: Output path buffer too small (Linux only)
nvwrite_ERR_PLATFORM: Operation not supported on this OS (e.g., list on Windows)
===================================================================
ENGINEERING NOTES
===================================================================
Freestanding:
In release builds (NDEBUG defined), no standard library functions are used.
This is to support other (FGL and non-FGL) projects where using libc just isn't possible.
Attributes:
Linux writes the standard EFI variable attributes 0x07 (Non‑volatile + BootService
+ Runtime). Windows uses the default attributes from SetFirmwareEnvironmentVariable.
Endianness: The Linux code assumes little‑endian for the attributes header
(the common case for x86/ARM). For big‑endian platforms, add le32toh/htole32
conversions.
Security: Variable names are NOT validated for path components (.., /). This is
deliberate. It is caller's responsibility to do so.
Windows enumeration: Not provided due to lack of a stable public API. Soon though...!
===================================================================
CREDITS
===================================================================
Serexp @ Futuristic Gadgets Laboratory.
Words from the author:
Another FGL classic. Only thing I did wrong was not writing it sooner.
Come say hi, contact @ https://serexp.lain.la
===================================================================
License
===================================================================
Check license.txt