AxlBlock — block-device enumeration + media descriptors
Block-device enumeration via EFI_BLOCK_IO_PROTOCOL.
Header: <axl/axl-block.h>. This is the low-level counterpart to
<axl/axl-fs.h>: AxlFs gives path-based file access over mounted
volumes, while AxlBlock enumerates the underlying raw block devices
(disks, partitions, CD-ROMs, RAM disks) and reports each one’s media
descriptor — geometry and media state. Scope is enumeration + the
media readout; block read/write is out of scope (use AxlFs for data).
Lazy on first call: AxlBlock locates the firmware-installed block-I/O
handles once with LocateHandleBuffer and caches the set for the
image lifetime. On platforms with no block devices every call returns
NULL / AXL_ERR cleanly.
Cursor-style enumeration matches axl_usb_next / axl_acpi_find_next,
but returns the firmware AxlHandle directly so position is recovered
from the handle you pass back — there is no hidden shared cursor, so
independent (even nested) walks over the cached set don’t interfere:
AxlHandle h = NULL;
while ((h = axl_block_next(h)) != NULL) {
AxlBlockMedia m;
if (axl_block_get_media(h, &m) == AXL_OK && m.media_present) {
uint64_t capacity = (m.last_block + 1) * m.block_size;
axl_printf("block dev: %u-byte sectors, %llu bytes%s\n",
m.block_size, (unsigned long long)capacity,
m.read_only ? " (read-only)" : "");
}
}
Device-path text needs no extra API: the same AxlHandle resolves
through the existing axl_handle_get_protocol(h, "device-path", ...)
axl_device_path_to_text()(both in<axl/axl-sys.h>).
Fields in AxlBlockMedia are raw readouts of EFI_BLOCK_IO_MEDIA;
the caller derives presentation values (capacity, device type). The
geometry fields (block_size, last_block) are meaningful only when
media_present is true — an empty removable slot may report stale or
zero values.
API Reference
Block-device enumeration and media descriptors.
Enumerates the handles that publish the firmware’s block-I/O protocol (raw block devices: disks, partitions, CD-ROMs, RAM disks) and exposes each device’s media descriptor as a typed struct. This is the low-level counterpart to <axl/axl-fs.h>: AxlFs gives path-based file access over mounted volumes, while AxlBlock enumerates the underlying block devices and reports their geometry and media state.
Cursor-style iteration matches the other platform readers (AxlPci, AxlUsb, AxlAcpi). axl_block_next walks the block handles; the returned AxlHandle feeds the typed reader below:
AxlHandle h = NULL;
while ((h = axl_block_next(h)) != NULL) {
AxlBlockMedia m;
if (axl_block_get_media(h, &m) == AXL_OK && m.media_present) {
uint64_t capacity = (m.last_block + 1) * m.block_size;
// ... report device ...
}
}
Device-path text needs no new API: the same AxlHandle resolves through the existing axl_handle_get_protocol(h, "device-path", ...) + axl_device_path_to_text() (both in <axl/axl-sys.h>).
Scope is enumeration + the media descriptor. Block read/write is out of scope — diagnostic and inventory tools need the device list and geometry, not a block-level I/O path (use AxlFs for data access).
Functions
-
AxlHandle axl_block_next(AxlHandle prev)
Iterate handles publishing the block-I/O protocol.
Cursor-style enumeration: pass NULL to get the first block handle, then pass each returned handle back to get the next. Returns NULL once the enumeration is exhausted (including when no block devices exist).
The handle set is snapshotted from the firmware on the first call and cached for the image lifetime (like AxlUsb) — a device hot-added afterward will not appear; the cache mirrors the boot device set. Position is recovered from the handle you pass back, not from a hidden shared cursor, so iteration carries no global state: passing NULL — or any handle not in the cached set — starts again from the first device, and independent walks (even nested ones over the same stable set) do not interfere.
The returned handle is owned by the firmware — do not free it. It is valid to pass to
axl_block_get_mediaand toaxl_handle_get_protocol(h, "device-path", ...).- Parameters:
prev – previous handle, or NULL to start
- Returns:
next block-I/O handle, or NULL at end of enumeration.
-
int axl_block_get_media(AxlHandle handle, AxlBlockMedia *out)
Read a block device’s media descriptor.
- Parameters:
handle – handle from axl_block_next
out – [out] populated on success
- Returns:
AXL_OK on success, AXL_ERR if
handledoes not publish the block-I/O protocol oroutis NULL.
-
struct AxlBlockMedia
- #include <axl-block.h>
Media descriptor for a block device.
Typed projection of the firmware’s
EFI_BLOCK_IO_MEDIA. Fields are raw readouts; the consumer derives presentation values such as capacity ((last_block + 1) * block_size) and device type.The geometry fields (
block_size,last_block) are meaningful only whenmedia_presentis true — for an empty removable slot (CD-ROM, card reader) the firmware may report stale or zero values, so capacity must be computed only after checkingmedia_present.Physical-geometry and alignment fields the firmware also tracks (
IoAlign, and the revision-gatedLowestAlignedLba/LogicalBlocksPerPhysicalBlock/OptimalTransferLengthGranularity) are intentionally omitted: they require gating on the media revision and matter only to a block-level I/O path, which is out of scope for enumeration.Public Members
-
uint32_t media_id
media ID; a change between reads of the same handle means the media was swapped (cached geometry is then stale)
-
bool removable_media
the media is removable (CD-ROM, USB stick), not that the device is hot-pluggable
-
bool media_present
media is currently present and accessible
-
bool logical_partition
handle is a logical partition, not a whole device
-
bool read_only
media is write-protected
-
bool write_caching
device has a write-back cache enabled
-
uint32_t block_size
logical (not physical) block size in bytes
-
uint64_t last_block
LBA of the last addressable block (count = last_block + 1); valid only when media_present.
-
uint32_t media_id