AxlSys – System Utilities
System operations, environment variables, time, NVRAM storage, driver lifecycle, and hex dump.
Headers:
<axl/axl-sys.h>– System operations (reset, GUID, device map refresh)<axl/axl-env.h>– Environment variables and working directory<axl/axl-time.h>– Wall-clock time and monotonic timestamps<axl/axl-nvstore.h>– UEFI NVRAM variable access<axl/axl-driver.h>– Driver binding and lifecycle<axl/axl-hexdump.h>– Hex/ASCII dump formatting
Overview
GUIDs
UEFI identifies protocols, variables, and services by 128-bit GUIDs.
AXL provides AxlGuid (standard C types, no UEFI headers needed)
and the AXL_GUID macro for initialization:
AxlGuid my_guid = AXL_GUID(0x12345678, 0xabcd, 0xef01,
0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01);
if (axl_guid_cmp(&a, &b) == 0) {
// GUIDs are equal
}
Firmware Globals
After AXL_APP or axl_driver_init, these globals are available
(typed when <uefi/axl-uefi.h> is included):
gST– System Table (EFI_SYSTEM_TABLE *)gBS– Boot Services (EFI_BOOT_SERVICES *)gRT– Runtime Services (EFI_RUNTIME_SERVICES *)gImageHandle– handle of the running application or driver
NVRAM Variables
Read and write persistent UEFI variables (survive reboot):
// Read
uint8_t secure_boot;
size_t sz = sizeof(secure_boot);
if (axl_nvstore_get("global", "SecureBoot", &secure_boot, &sz) == 0) {
axl_printf("SecureBoot: %s\n", secure_boot ? "on" : "off");
}
// Write
axl_nvstore_set("app", "last-run", timestamp, timestamp_len,
AXL_NVSTORE_BOOT | AXL_NVSTORE_NV);
Driver Lifecycle
Build DXE drivers with axl-cc --type driver. The driver entry point
is DriverEntry (not main). Call axl_driver_init to set up
the AXL runtime:
EFI_STATUS EFIAPI DriverEntry(EFI_HANDLE ImageHandle,
EFI_SYSTEM_TABLE *SystemTable) {
axl_driver_init(ImageHandle, SystemTable);
axl_printf("Driver loaded\n");
// ...
}
See sdk/examples/driver.c for a complete example.
AxlSys
Defines
-
AXL_GUID(d1, d2, d3, d4_0, d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7)
Initialize an AxlGuid from literal values.
Usage: AxlGuid
g = AXL_GUID(0x12345678, 0xABCD, 0xEF01,
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01);
-
AXL_RESET_COLD
cold reset (full power cycle)
-
AXL_RESET_WARM
warm reset (CPU reset, memory preserved)
-
AXL_RESET_SHUTDOWN
power off
Functions
-
static inline bool axl_guid_cmp(const AxlGuid *a, const AxlGuid *b)
Compare two GUIDs for equality.
- Returns:
true if equal.
-
bool axl_device_path_has_vendor(void *device_path, const AxlGuid *guid)
Check if a device path contains a vendor node with the given GUID.
Walks the device path node chain looking for a hardware vendor node (type 0x01, subtype 0x04) whose GUID matches
guid.- Parameters:
device_path – device path (from “device-path” service)
guid – vendor GUID to match
- Returns:
true if a matching vendor node is found.
-
void axl_reset(int type)
Reset or shut down the system.
Does not return on success.
- Parameters:
type – AXL_RESET_COLD, AXL_RESET_WARM, or AXL_RESET_SHUTDOWN
-
int axl_map_refresh(void)
Rescan device-to-filesystem mappings.
Equivalent to the Shell “map -r” command. Call after hot-plugging a USB drive or after a driver installs a new filesystem.
- Returns:
0 on success, -1 on error.
-
int axl_sys_get_firmware_info(AxlFirmwareInfo *info)
Get firmware information (vendor, revision, spec version).
- Parameters:
info – [out] receives firmware info
- Returns:
0 on success, -1 on error.
-
int axl_sys_get_memory_size(uint64_t *total_bytes)
Get total usable memory size in bytes.
Queries the firmware memory map and sums all usable regions.
- Parameters:
total_bytes – [out] receives total usable RAM
- Returns:
0 on success, -1 on error.
-
int axl_handle_get_service(void *handle, const char *name, void **interface)
Get a service interface from a specific handle.
- Parameters:
handle – handle from axl_service_enumerate
name – service name (e.g., “device-path”, “simple-fs”)
interface – [out] service interface pointer
- Returns:
0 on success, -1 if not found.
-
void axl_stall(uint64_t microseconds)
Busy-wait for a duration.
- Parameters:
microseconds – duration in microseconds
-
int axl_service_find(const char *name, void **interface)
Find a system service by name.
Looks up a named service in the platform service registry. Well-known names: “smbios”, “shell”, “simple-network”, “simple-fs”.
- Parameters:
name – service name
interface – [out] service interface pointer
- Returns:
0 on success, -1 if not found.
-
int axl_service_enumerate(const char *name, void ***handles, size_t *count)
Enumerate all handles providing a named service.
Caller frees the returned handles array with axl_free().
- Parameters:
name – service name
handles – [out] array of handles
count – [out] number of handles
- Returns:
0 on success (count may be 0), -1 on error.
-
int axl_service_register(const char *name, void *interface, void **handle)
Register a service on a handle.
Creates a new handle if *handle is NULL.
- Parameters:
name – service name
interface – service interface to install
handle – [in/out] handle (NULL to create new)
- Returns:
0 on success, -1 on error.
-
int axl_service_unregister(void *handle, const char *name, void *interface)
Unregister a service from a handle.
- Parameters:
handle – handle from axl_service_register
name – service name
interface – interface to remove
- Returns:
0 on success, -1 on error.
-
int axl_service_register_multiple(void **handle, ...)
Register multiple services on a handle atomically.
Installs one or more services on the same handle in one operation. If any fails, none are installed. Creates a new handle if *handle is NULL. Pass name/interface pairs followed by NULL:
void *h = NULL; axl_service_register_multiple(&h, "simple-fs", &my_fs, "device-path", &my_dp, NULL);
- Parameters:
handle – [in/out] handle (NULL to create new)
- Param :
name, interface pairs, terminated by NULL
- Returns:
0 on success, -1 on error.
-
struct AxlGuid
- #include <axl-sys.h>
UEFI-compatible GUID in standard C types.
Binary-compatible with EFI_GUID. Use in public API so consumer apps don’t need
<uefi/axl-uefi.h>for GUID operations.
-
struct AxlFirmwareInfo
- #include <axl-sys.h>
Firmware information.
AxlEnv
Functions
-
char *axl_getenv(const char *name)
Get a shell environment variable.
Returns a UTF-8 copy of the variable’s value. Caller frees with axl_free().
- Parameters:
name – variable name (UTF-8)
- Returns:
value string, or NULL if not found.
-
int axl_setenv(const char *name, const char *value, bool overwrite)
Set a shell environment variable.
- Parameters:
name – variable name (UTF-8)
value – value (UTF-8)
overwrite – if false, don’t replace existing value
- Returns:
0 on success, -1 on error.
-
int axl_unsetenv(const char *name)
Remove a shell environment variable.
- Parameters:
name – variable name (UTF-8)
- Returns:
0 on success, -1 on error.
AxlTime
Functions
-
size_t axl_time_format(char *buf, size_t buf_size)
Format current time as ISO 8601 with microseconds.
Example: “2026-03-27T14:05:32.123456”
- Parameters:
buf – destination buffer (at least 28 bytes)
buf_size – size of buffer
- Returns:
characters written (excluding NUL), 0 on error.
-
void axl_sleep(uint64_t seconds)
Sleep for the specified number of seconds. CPU-idle, not spinning.
-
void axl_msleep(uint64_t milliseconds)
Sleep for the specified number of milliseconds. CPU-idle.
-
void axl_usleep(uint64_t microseconds)
Sleep for the specified number of microseconds. CPU-idle.
-
void axl_spin_sleep(uint64_t seconds)
Busy-wait for the specified number of seconds.
-
void axl_spin_msleep(uint64_t milliseconds)
Busy-wait for the specified number of milliseconds.
-
void axl_spin_usleep(uint64_t microseconds)
Busy-wait for the specified number of microseconds.
-
uint64_t axl_time_get_ms(void)
Get a monotonic millisecond counter.
Based on firmware time — not wall-clock accurate but monotonically increasing within a boot session. Useful for measuring elapsed time.
- Returns:
milliseconds since an arbitrary epoch (typically boot).
AxlNvStore
Defines
-
AXL_NV_VOLATILE
lost on reboot
-
AXL_NV_PERSISTENT
survives reboot (non-volatile)
-
AXL_NV_BOOT
accessible during boot services
-
AXL_NV_RUNTIME
accessible at runtime
Functions
-
int axl_nvstore_get(const char *ns, const char *key, void *buf, size_t *size)
Read a value from non-volatile storage.
- Parameters:
ns – namespace (e.g., “global”, “app”)
key – variable name (UTF-8)
buf – output buffer
size – [in/out] buffer size / bytes read
- Returns:
0 on success, -1 on error (variable not found, buffer too small, etc.). On buffer-too-small, size is updated to the required size.
-
int axl_nvstore_set(const char *ns, const char *key, const void *buf, size_t size, uint32_t flags)
Write a value to non-volatile storage.
- Parameters:
ns – namespace (e.g., “global”, “app”)
key – variable name (UTF-8)
buf – data to write
size – data size in bytes
flags – AXL_NV_* flags
- Returns:
0 on success, -1 on error.
AxlDriver
Typedefs
-
typedef void *AxlDriverHandle
Opaque handle to a loaded driver image.
Functions
-
int axl_driver_load(const char *path, AxlDriverHandle *handle)
Load a driver image from a file path.
Loads the .efi file into memory but does not start it.
- Parameters:
path – path to .efi driver (UTF-8)
handle – [out] receives driver handle
- Returns:
0 on success, -1 on error.
-
int axl_driver_start(AxlDriverHandle handle)
Start a loaded driver image.
Calls the driver’s entry point. The driver registers its binding protocol(s) but does not yet bind to devices.
- Parameters:
handle – driver handle from axl_driver_load
- Returns:
0 on success, -1 on error.
-
int axl_driver_connect(AxlDriverHandle handle)
Connect a driver to all matching device handles.
Triggers the driver’s Supported/Start sequence for each compatible device. Call after axl_driver_start.
- Parameters:
handle – driver handle
- Returns:
0 on success, -1 on error.
-
int axl_driver_disconnect(AxlDriverHandle handle)
Disconnect a driver from all devices.
Triggers the driver’s Stop sequence for each bound device.
- Parameters:
handle – driver handle
- Returns:
0 on success, -1 on error.
-
int axl_driver_unload(AxlDriverHandle handle)
Unload a driver image from memory.
The driver must be disconnected first.
- Parameters:
handle – driver handle
- Returns:
0 on success, -1 on error.
-
int axl_driver_set_load_options(AxlDriverHandle handle, const void *data, size_t size)
Set load options on a loaded driver image.
Provides configuration data (e.g., a URL) that the driver reads from EFI_LOADED_IMAGE_PROTOCOL.LoadOptions during startup. The data is copied internally — caller’s buffer can be freed after. Pass NULL data to clear load options. Call between axl_driver_load and axl_driver_start.
- Parameters:
handle – driver handle from axl_driver_load
data – option data (copied; NULL to clear)
size – option data size in bytes
- Returns:
0 on success, -1 on error.
-
void axl_driver_init(void *image_handle, void *system_table)
Initialize the AXL runtime for a DXE driver.
Drivers don’t use AXL_APP / int main(). Call this from DriverEntry to set up firmware table pointers (gST/gBS/gRT) and I/O streams so axl_printf, axl_malloc, etc. work.
EFI_STATUS EFIAPI DriverEntry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { axl_driver_init(ImageHandle, SystemTable); axl_printf("Driver loaded\n"); ... }
- Parameters:
image_handle – EFI_HANDLE from DriverEntry
system_table – EFI_SYSTEM_TABLE* from DriverEntry
-
int axl_driver_set_unload(void *unload_fn)
Set the unload callback for the current driver image.
Call from DriverEntry to register a cleanup function that runs when the driver is unloaded. The callback has EFIAPI calling convention — declare it as: EFI_STATUS EFIAPI MyUnload(EFI_HANDLE ImageHandle)
- Parameters:
unload_fn – EFIAPI unload function pointer
- Returns:
0 on success, -1 on error.
-
char *axl_driver_get_load_options(void)
Get the load options that were passed to the current image.
Returns a UTF-8 copy of the load options string. Caller frees with axl_free(). Useful for drivers that receive configuration (e.g., a URL) via LoadOptions.
- Returns:
options string, or NULL if no options or on error.
-
char *axl_driver_get_image_path(void)
Get the filesystem path the current image was loaded from.
Returns a UTF-8 path like “fs0:\drivers\MyDriver.efi”. Useful for finding companion files next to the driver. Caller frees with axl_free().
- Returns:
path string, or NULL if unavailable.
-
int axl_driver_connect_handle(void *handle)
Connect controllers on a specific handle.
Triggers driver binding for one handle (e.g., after installing a filesystem protocol on a new handle). More targeted than axl_driver_connect which reconnects all handles.
- Parameters:
handle – handle to connect (from axl_service_register, etc.)
- Returns:
0 on success, -1 on error.
-
int axl_driver_load_dir(const char *dir_path, const char *pattern, size_t *loaded_count)
Load, start, and connect all .efi drivers in a directory.
Scans
dir_pathfor files matchingpattern(glob, e.g. “*.efi”). Each matching file is loaded, started, and connected. On return,loaded_countreceives the number of drivers successfully started. Pass NULL forpatternto match all .efi files.- Parameters:
dir_path – directory to scan (UTF-8)
pattern – glob pattern (NULL = “*.efi”)
loaded_count – [out] number of drivers loaded (may be NULL)
- Returns:
0 on success (even if no drivers found), -1 on error.
AxlHexdump
Defines
-
AXL_HEX_GROUP_BYTE
-
AXL_HEX_GROUP_WORD
-
AXL_HEX_GROUP_DWORD
-
AXL_HEX_GROUP_QWORD
-
AXL_HEXDUMP_MAX_SIZE
-
AxlHexDumpLog(Level, Name, Data, Size, BytesPerLine, GroupSize)
Convenience macro that injects _AxlLogDomain, func, LINE.
Requires AXL_LOG_DOMAIN() in the source file.
Functions
-
void axl_hexdump(const char *name, const void *data, size_t size, size_t bytes_per_line, size_t group_size)
Print a hex+ASCII dump to stdout via axl_print().
- Parameters:
name – label printed above the dump (may be NULL)
data – buffer to dump
size – number of bytes
bytes_per_line – columns (0 = default 16, max 64)
group_size – grouping width (AXL_HEX_GROUP_*)
-
void axl_hexdump_to_log(int level, const char *domain, const char *func, int line, const char *name, const void *data, size_t size, size_t bytes_per_line, size_t group_size)
Emit a hex+ASCII dump through axl_log_full().
- Parameters:
level – log level (AXL_LOG_ERROR..AXL_LOG_TRACE)
domain – log domain
func – func
line – LINE
name – label printed above the dump (may be NULL)
data – buffer to dump
size – number of bytes
bytes_per_line – columns (0 = default 16, max 64)
group_size – grouping width (AXL_HEX_GROUP_*)