AxlSmbios — SMBIOS table access
SMBIOS table lookup and string extraction.
The SMBIOS spec defines a set of typed records — BIOS info, System info, Baseboard, Processor, Memory Array, etc. — that firmware publishes via the UEFI SMBIOS protocol. AxlSmbios provides a small, stable API for walking that table and pulling strings out of records.
Headers:
<axl/axl-smbios.h>— Table lookup, header walking, string extraction
Overview
#include <axl.h>
#include <axl/axl-smbios.h>
// Find the BIOS Information record (SMBIOS Type 0)
AxlSmbiosHeader *hdr = axl_smbios_find(AXL_SMBIOS_TYPE_BIOS_INFO);
if (hdr) {
const char *vendor = axl_smbios_get_string_utf8(hdr, 1); // vendor
const char *version = axl_smbios_get_string_utf8(hdr, 2); // version
axl_printf("BIOS: %s %s\n", vendor, version);
}
The table header is a fixed-length record followed by a
double-NUL-terminated list of ASCII strings referenced by 1-based
index from within the record. axl_smbios_get_string_utf8 resolves
those string indices to plain C strings.
Iterating All Records
To visit every record the firmware published — regardless of type:
AxlSmbiosHeader *h = NULL;
while ((h = axl_smbios_next(h)) != NULL) {
axl_printf("Type %u Handle 0x%04x Length %u\n",
h->Type, h->Handle, h->Length);
}
To iterate every record of a specific type (useful for enumerating
DIMMs, CPU cores, cache levels, etc.), use axl_smbios_find_next:
// Walk every Memory Device (Type 17) — one per DIMM slot
AxlSmbiosHeader *h = NULL;
while ((h = axl_smbios_find_next(AXL_SMBIOS_TYPE_MEMORY_DEVICE, h)) != NULL) {
// process DIMM record...
}
Common Type Constants
Use the AXL_SMBIOS_TYPE_* enum instead of bare type numbers — the
code reads better and greps cleaner. The enum covers the most common
records (BIOS, System, Baseboard, Chassis, Processor, Memory Device,
IPMI Device Info, end-of-table sentinel, etc.). For rarely-used types
(SMBIOS defines ~45), bare numbers are still fine.
Reading the Spec Version
unsigned char major, minor;
if (axl_smbios_version(&major, &minor) == 0) {
axl_printf("SMBIOS %u.%u\n", major, minor);
}
Useful for gating on fields that were added in later spec revisions (e.g. several Type 17 Memory Device fields are post-2.7).
Consumers
tools/sysinfouses SMBIOS to report BIOS, system, baseboard, and processor inventory.src/ipmi/axl-ipmi.cprobes SMBIOS Type 38 (IPMI Device Information) during transport auto-detection.
Notes
String accessors share a static 128-byte buffer; copy the result if you need to retain it across another call.
Only the first matching record is returned by
axl_smbios_find; a future addition (axl_smbios_next) would allow walking all records of a given type.
API Reference
Enums
Common SMBIOS table types. Values match the SMBIOS specification; use these constants instead of bare numbers for readability.
Values:
-
enumerator AXL_SMBIOS_TYPE_BIOS_INFO
BIOS Information.
-
enumerator AXL_SMBIOS_TYPE_SYSTEM_INFO
System Information (manufacturer, product, UUID)
-
enumerator AXL_SMBIOS_TYPE_BASEBOARD
Baseboard / Module.
-
enumerator AXL_SMBIOS_TYPE_CHASSIS
System Enclosure / Chassis.
-
enumerator AXL_SMBIOS_TYPE_PROCESSOR
Processor.
-
enumerator AXL_SMBIOS_TYPE_CACHE
Cache.
-
enumerator AXL_SMBIOS_TYPE_PORT_CONNECTOR
Port Connector.
-
enumerator AXL_SMBIOS_TYPE_SYSTEM_SLOTS
System Slots.
-
enumerator AXL_SMBIOS_TYPE_OEM_STRINGS
OEM Strings.
-
enumerator AXL_SMBIOS_TYPE_BIOS_LANGUAGE
BIOS Language Information.
-
enumerator AXL_SMBIOS_TYPE_PHYSICAL_MEMORY
Physical Memory Array.
-
enumerator AXL_SMBIOS_TYPE_MEMORY_DEVICE
Memory Device (per DIMM)
-
enumerator AXL_SMBIOS_TYPE_MEMORY_ARRAY_MAP
Memory Array Mapped Address.
-
enumerator AXL_SMBIOS_TYPE_SYSTEM_BOOT
System Boot Information.
-
enumerator AXL_SMBIOS_TYPE_IPMI_DEVICE_INFO
IPMI Device Information (transport, address)
-
enumerator AXL_SMBIOS_TYPE_MGMT_HOST_INTERFACE
Management Controller Host Interface (Redfish, OEM, …)
-
enumerator AXL_SMBIOS_TYPE_END
End-of-table sentinel.
-
enumerator AXL_SMBIOS_TYPE_BIOS_INFO
IPMI interface type codes (Type 38 offset 0x04).
Values:
-
enumerator AXL_SMBIOS_IPMI_UNKNOWN
-
enumerator AXL_SMBIOS_IPMI_KCS
-
enumerator AXL_SMBIOS_IPMI_SMIC
-
enumerator AXL_SMBIOS_IPMI_BT
-
enumerator AXL_SMBIOS_IPMI_SSIF
-
enumerator AXL_SMBIOS_IPMI_UNKNOWN
Management Controller Host Interface types (Type 42 offset 0x04).
Values:
-
enumerator AXL_SMBIOS_HIF_KCS
Keyboard Controller Style.
-
enumerator AXL_SMBIOS_HIF_UART_8250
-
enumerator AXL_SMBIOS_HIF_UART_16450
-
enumerator AXL_SMBIOS_HIF_UART_16550
-
enumerator AXL_SMBIOS_HIF_UART_16650
-
enumerator AXL_SMBIOS_HIF_UART_16750
-
enumerator AXL_SMBIOS_HIF_UART_16850
-
enumerator AXL_SMBIOS_HIF_NETWORK
Network Host Interface (used for Redfish)
-
enumerator AXL_SMBIOS_HIF_OEM
OEM-defined.
-
enumerator AXL_SMBIOS_HIF_KCS
Functions
-
int axl_smbios_read_bios_info(AxlSmbiosBiosInfo *out)
Read Type 0 (BIOS Information) from the SMBIOS table.
- Returns:
0 on success, -1 if no Type 0 record is present.
-
int axl_smbios_read_system_info(AxlSmbiosSystemInfo *out)
Read Type 1 (System Information) from the SMBIOS table.
- Returns:
0 on success, -1 if no Type 1 record is present.
-
int axl_smbios_read_baseboard(AxlSmbiosBaseboardInfo *out)
Read Type 2 (Baseboard Information) from the SMBIOS table.
- Returns:
0 on success, -1 if no Type 2 record is present.
-
int axl_smbios_read_chassis(AxlSmbiosChassisInfo *out)
Read Type 3 (System Enclosure / Chassis) from the SMBIOS table.
- Returns:
0 on success, -1 if no Type 3 record is present.
-
int axl_smbios_read_processor(AxlSmbiosHeader *hdr, AxlSmbiosProcessorInfo *out)
Read a Type 4 (Processor) record the caller already located.
Firmware publishes one Type 4 per socket. Enumerate with
axl_smbios_find_next(AXL_SMBIOS_TYPE_PROCESSOR, prev)and call this for each result.- Returns:
0 on success, -1 if hdr is NULL or the wrong record type.
-
int axl_smbios_read_memory_device(AxlSmbiosHeader *hdr, AxlSmbiosMemoryDevice *out)
Read a Type 17 (Memory Device) record the caller already located.
Firmware publishes one Type 17 per DIMM slot (populated or not). Enumerate with
axl_smbios_find_next(AXL_SMBIOS_TYPE_MEMORY_DEVICE, prev)and call this for each result.- Returns:
0 on success, -1 if hdr is NULL or the wrong record type.
-
int axl_smbios_read_ipmi_device_info(AxlSmbiosIpmiDeviceInfo *out)
Read Type 38 (IPMI Device Information).
Firmware publishes at most one Type 38 record (the single BMC). This is what AxlIpmi’s transport auto-detector reads to decide between KCS, SMIC, BT, and SSIF.
- Returns:
0 on success, -1 if no Type 38 record is present.
-
int axl_smbios_read_host_interface(AxlSmbiosHeader *hdr, AxlSmbiosHostInterface *out)
Read a Type 42 (Management Controller Host Interface) record.
Firmware may publish multiple Type 42 records (one per interface); enumerate with
axl_smbios_find_next(AXL_SMBIOS_TYPE_MGMT_HOST_INTERFACE, prev)and call this for each result. Requires SMBIOS 3.0 or later for the modern variable-length layout; older spec versions of Type 42 are not supported and return -1.- Returns:
0 on success, -1 if hdr is NULL, wrong type, or the record layout is too old to decode.
-
int axl_smbios_find_redfish_host_interface(AxlSmbiosHeader **hdr_out, AxlSmbiosHostInterface *iface_out)
Find the first Type 42 record advertising Redfish over IP.
Scans Type 42s for
interface_type == AXL_SMBIOS_HIF_NETWORKwith aAXL_SMBIOS_HIP_REDFISH_OVER_IPprotocol entry. Common use: an in-band tool that wants to talk Redfish to the local BMC without network probing.- Parameters:
hdr_out – optional — receives the matching Type 42 header
iface_out – optional — receives the parsed interface (typed reader output)
- Returns:
0 on success, -1 if nothing matches.
-
int axl_smbios_get_system_uuid(uint8_t out[16])
Get the system UUID with the endian-swap SMBIOS requires applied.
SMBIOS stores the UUID’s first three fields little-endian on the wire (since spec 2.6), but the RFC 4122 “standard” /
dmidecodedisplay form expects big-endian. This helper returns the RFC 4122 byte order so you can feed the result to anything expecting canonical UUID bytes.- Returns:
0 on success, -1 if no Type 1 record or UUID is unset (all 0x00 or all 0xFF per the spec’s “not present” markers).
-
unsigned short *axl_smbios_get_string(AxlSmbiosHeader *hdr, unsigned char string_index)
Get a string from an SMBIOS table’s string area (UCS-2).
Returns a pointer to a static 128-char unsigned short buffer — caller must use the value before the next call (not reentrant).
- Parameters:
hdr – SMBIOS table header
string_index – 1-based string index (0 returns empty string)
- Returns:
pointer to static unsigned short buffer.
-
const char *axl_smbios_get_string_utf8(AxlSmbiosHeader *hdr, unsigned char string_index)
Get a string from an SMBIOS table’s string area (UTF-8).
Returns a pointer to a static 128-char buffer — caller must use the value before the next call (not reentrant).
- Parameters:
hdr – SMBIOS table header
string_index – 1-based string index (0 returns “”)
- Returns:
pointer to static char buffer, or “” if not found.
-
AxlSmbiosHeader *axl_smbios_find(unsigned char type)
Find the first SMBIOS table of a given type.
- Parameters:
type – SMBIOS table type (e.g. 0 for BIOS, 1 for System)
- Returns:
pointer to table header, or NULL if not found.
-
AxlSmbiosHeader *axl_smbios_find_next(unsigned char type, AxlSmbiosHeader *prev)
Find the next SMBIOS table of a given type after prev.
Pass NULL as prev to find the first (same as axl_smbios_find). Use in a loop to enumerate all tables of a type:
AxlSmbiosHeader *h = NULL; while ((h = axl_smbios_find_next(17, h)) != NULL) { // process each Type 17 (Memory Device) entry }
- Parameters:
type – SMBIOS table type
prev – previous result (NULL to start from beginning)
- Returns:
pointer to next table header, or NULL if no more.
-
AxlSmbiosHeader *axl_smbios_next(AxlSmbiosHeader *prev)
Iterate every SMBIOS record regardless of type.
Pass NULL for the first call; pass the previous result for subsequent calls. Returns NULL when there are no more records. Walks the table in the order firmware published it, stopping at the Type 127 end-of-table sentinel.
AxlSmbiosHeader *h = NULL; while ((h = axl_smbios_next(h)) != NULL) { axl_printf("Type %u Handle 0x%04x Length %u\n", h->Type, h->Handle, h->Length); }
- Parameters:
prev – previous result (NULL to start from beginning)
- Returns:
pointer to next table header, or NULL if no more.
-
int axl_smbios_version(unsigned char *major, unsigned char *minor)
Report the SMBIOS specification version published by firmware.
Useful for gating features on the spec version — some Type 17 Memory Device fields were added in SMBIOS 2.7, and Type 43 TPM Device requires 3.1 or later.
- Parameters:
major – written with major version (e.g. 3)
minor – written with minor version (e.g. 1)
- Returns:
0 on success, -1 if no SMBIOS table was found.
-
struct AxlSmbiosHeader
- #include <axl-smbios.h>
SMBIOS table header (standard C types, matches SMBIOS spec layout).
axl-smbios.h:
UEFI SMBIOS helpers — string extraction and table lookup.
-
struct AxlSmbiosBiosInfo
- #include <axl-smbios.h>
Type 0 — BIOS Information.
-
struct AxlSmbiosSystemInfo
- #include <axl-smbios.h>
Type 1 — System Information.
Public Members
-
const char *manufacturer
-
const char *product_name
-
const char *version
-
const char *serial_number
-
const char *sku
NULL if not published (spec 2.4+)
-
const char *family
NULL if not published (spec 2.4+)
-
uint8_t uuid[16]
RFC 4122 byte order (see note below)
-
bool has_uuid
false if UUID field is unset (all 0x00 or 0xFF)
-
const char *manufacturer
-
struct AxlSmbiosBaseboardInfo
- #include <axl-smbios.h>
Type 2 — Baseboard Information.
-
struct AxlSmbiosChassisInfo
- #include <axl-smbios.h>
Type 3 — System Enclosure / Chassis.
-
struct AxlSmbiosProcessorInfo
- #include <axl-smbios.h>
Type 4 — Processor.
Public Members
-
const char *socket_designation
-
const char *manufacturer
-
const char *version
-
const char *serial_number
-
const char *asset_tag
-
const char *part_number
-
uint8_t family
SMBIOS processor-family code.
-
uint16_t current_speed_mhz
-
uint16_t max_speed_mhz
-
uint8_t core_count
0 if not published (spec 2.5+)
-
uint8_t thread_count
0 if not published
-
uint8_t status
CPU socket populated + enabled bits.
-
const char *socket_designation
-
struct AxlSmbiosMemoryDevice
- #include <axl-smbios.h>
Type 17 — Memory Device (per DIMM slot).
Public Members
-
const char *device_locator
-
const char *bank_locator
-
const char *manufacturer
-
const char *part_number
-
const char *serial_number
-
const char *asset_tag
-
uint32_t size_mb
0 if slot is empty
-
uint16_t speed_mhz
0 if unknown
-
uint8_t memory_type
SMBIOS memory type (DDR4=0x1A, DDR5=0x22, …)
-
const char *device_locator
-
struct AxlSmbiosIpmiDeviceInfo
- #include <axl-smbios.h>
Type 38 — IPMI Device Information.
Public Members
-
uint8_t interface_type
AXL_SMBIOS_IPMI_* (KCS, SMIC, BT, SSIF, …)
-
uint8_t spec_major
IPMI spec revision major (high nibble of byte 0x05)
-
uint8_t spec_minor
IPMI spec revision minor (low nibble of byte 0x05)
-
uint8_t i2c_target_address
BMC slave address on SMBus/SSIF (0 if N/A)
-
uint8_t nv_storage_address
NV storage device address (0xFF = none)
-
uint64_t base_address
Interface base address (I/O or MMIO, see is_memory_mapped)
-
bool is_memory_mapped
true = MMIO, false = I/O port
-
uint8_t interrupt_number
0 = no interrupt
-
uint8_t interface_type
-
struct AxlSmbiosHostInterfaceProtocol
- #include <axl-smbios.h>
Type 42 — Management Controller Host Interface, one protocol record.
-
struct AxlSmbiosHostInterface
- #include <axl-smbios.h>
Type 42 — Management Controller Host Interface.
Public Members
-
uint8_t interface_type
AXL_SMBIOS_HIF_*.
-
uint8_t interface_data_len
length of
interface_data
-
const uint8_t *interface_data
interface-specific bytes (pointer into SMBIOS table)
-
uint8_t protocol_count
number of entries in
protocols
-
AxlSmbiosHostInterfaceProtocol protocols[8]
capped at 8 — real firmware emits 1-2
-
uint8_t interface_type