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/sysinfo uses SMBIOS to report BIOS, system, baseboard, and processor inventory.

  • src/ipmi/axl-ipmi.c probes 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.

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

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.

Management Controller Host Interface protocols (Type 42 protocol record).

Values:

enumerator AXL_SMBIOS_HIP_IPMI
enumerator AXL_SMBIOS_HIP_MCTP
enumerator AXL_SMBIOS_HIP_REDFISH_OVER_IP

Requires SMBIOS 3.2+.

enumerator AXL_SMBIOS_HIP_OEM

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_NETWORK with a AXL_SMBIOS_HIP_REDFISH_OVER_IP protocol 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” / dmidecode display 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.

Public Members

uint8_t Type
uint8_t Length
uint16_t Handle
struct AxlSmbiosBiosInfo
#include <axl-smbios.h>

Type 0 — BIOS Information.

Public Members

const char *vendor
const char *version
const char *release_date
uint8_t major_release

0xFF if firmware didn’t publish

uint8_t minor_release

0xFF if firmware didn’t publish

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)

struct AxlSmbiosBaseboardInfo
#include <axl-smbios.h>

Type 2 — Baseboard Information.

Public Members

const char *manufacturer
const char *product_name
const char *version
const char *serial_number
const char *asset_tag
struct AxlSmbiosChassisInfo
#include <axl-smbios.h>

Type 3 — System Enclosure / Chassis.

Public Members

const char *manufacturer
const char *version
const char *serial_number
const char *asset_tag
uint8_t type

Low 7 bits; 0x80 bit (lock) stripped.

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.

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, …)

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

struct AxlSmbiosHostInterfaceProtocol
#include <axl-smbios.h>

Type 42 — Management Controller Host Interface, one protocol record.

Public Members

uint8_t protocol_type

AXL_SMBIOS_HIP_* value.

uint8_t data_len

length of data

const uint8_t *data

protocol-specific payload (pointer into SMBIOS table)

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