2.5. Fastboot handler internals (FastbootLib)

This page documents the implementations behind ABL’s fastboot commands — the download transport, getvar variable publishing, and the flash/erase/boot handlers — i.e. QcomModulePkg/Library/FastbootLib. It is scoped to handler internals and the command-registration mechanism; the command surface (the static cmd_list table, the enumeration of 14 commands, and the “no bootloader-unlock command” finding) is owned by ABL overview, key handling, fastboot and is not restated here. Lock/unlock state semantics are on AVB enforcement code path (LoadImageAndAuth / libavb). RVAs are LinuxLoader-relative (= DXE file offset − 0xb8).

2.5.1. Entry and command registration

LinuxLoaderEntry reaches fastboot through FastbootInitialize (the Launching fastboot path, ABL entry point and top-level orchestration). In the binary the FastbootLib code forms a large merged cluster around RVA 0x2d1200x3043c (radare2 folds FastbootInitialize / FastbootCommandSetup / FastbootRegister / the getvar publishers together); the download handler sits separately at 0x32888.

Registration is not a jump through the static {name,handler} array by itself. FastbootCommandSetup walks a cmd_list[] = {{name, cb}, …} and calls FastbootRegister (name, cb) for each, which builds a runtime linked list of command descriptors that the dispatcher searches by longest-prefix match. That is why ABL overview, key handling, fastboot finds getvar: / download: / the oem verbs in the static array at RVA 0x4b8c0 but sees flash: / erase: / boot “registered individually” — those are registered by the same FastbootRegister mechanism into the same list, just from separate registration sites, so their names do not sit in the pointer-scanned array.

2.5.2. Download transport (CmdDownload, RVA 0x32888)

CmdDownload implements download:<hexsize>. Its embedded string set identifies it as the exact download: handler at RVA 0x32888 that ABL overview, key handling, fastboot lists (the strings below are the evidence for that identification, not for the handler’s internal correctness):

  • Parse the requested size (Failed to get the number of bytes to download, ERROR: Fail to get the number of bytes to download.).

  • Bound it against the max (Requested download size is more than max allowed, ERROR: Data size (%d) is more than max download size (%d)).

  • Acknowledge with the 12-byte DATA%08x reply (CmdDownload: Send 12 %a) and stream (Downloading %d bytes).

The bulk transfer runs through FastbootMain.c: the USB device protocol’s completion callback invokes DataReady (BytesCompleted, FastbootDloadBuffer ()), and outbound replies use UsbDeviceProtocol->Send (ENDPOINT_IN, GetXfrSize (), …). GetXfrSize sets the per-transfer chunk; mBytesReceivedSoFar tracks progress into the download buffer.

The download buffer is a single large allocation made at FastbootInitialize time (Not enough memory to Allocate Fastboot Buffer, Fastboot Buffer Size allocated: %ld, ERROR: Allocation fail for minimim buffer for fastboot). Its size is what max-download-size reports to the host (below).

2.5.3. getvar variable publishing (FastbootInitialize cluster, RVA 0x2fe3c / 0x30518)

FastbootInitialize publishes the getvar variables via FastbootPublishVar and registers dynamic getters. Variables materialised as literals in the 0x2d1200x30518 cluster:

max-download-size, version-bootloader, partition-type:, partition-size:, erase-block-size, slot-count, current-slot, has-slot:boot / has-slot:system / has-slot:modem, slot-successful: / slot-unbootable: / slot-retry-count:, parallel-download-flash, getvar:partition-type, androidboot.vbmeta.device. The getvar: dispatcher itself is the small handler at RVA 0x325dc (ABL overview, key handling, fastboot); it resolves all and per-variable queries against the published set.

2.5.4. Flash and erase handlers

The flash/erase implementations are present in the 0x2d1200x3043c cluster, backed by a partition/LUN layer around RVA 0x21db0 / 0x230c8 and an erase-block-protocol path in the 0x460000x48000 region:

  • Flash: multi-threaded/parallel flash (InitMultiThreadEnv successfully, will use thread to flash, Failed to creat event for waiting flash completely, FLASH, parallel-download-flash), sparse/meta image handling, and LUN selection (Boot lun mismatch switch from 1 to 2, Switching the boot lun from 1 to 2, Error getting block IO handle for Lun:%x). Battery gating: Error battery voltage: %d Requireed voltage: %d, can flash: %d.

  • Erase: erase-block protocol use (Unable to locate Erase block protocol handle:%r, Unable to Erase Block: %r, Waiting for the erase event to signal the completion), plus EraseUserKey handling (EraseUserKey DeviceInfo not initalized).

Lock-state enforcement is present but expressed differently from the matched QSSI12 source: the binary carries Snapshot Cancel is not allowed in Lock State and the devinfo lock read (AVB enforcement code path (LoadImageAndAuth / libavb)), but not the QSSI12 flash/erase guard strings.

Warning

Upstream divergence (version gap). The matched QSSI12 FastbootCmds.c guards flash/erase with "Flashing is not allowed in Lock State" / "Erase is not allowed in Lock State" / "No data to flash" / "Invalid Lun number passed" and implements fastboot flash avb_custom_key ("Flashing avb_custom_key failed"). None of these strings exist in this Android-11 binary. The flash/erase capability is real (the FLASH/erase/erase-block/multithread strings above), but its message set — and the avb_custom_key custom-AVB-key feature — predate the QSSI12 source. Do not attribute the QSSI12 flash/erase text or the avb_custom_key command to this build. Recorded as a deviation row in ABL function map and upstream-source correlation.

2.5.5. Boot handler

The boot command (fastboot boot — RAM-boot a supplied image) is registered individually (ABL overview, key handling, fastboot). The boot-dispatch strings Booting Into Recovery Mode / Booting Into Mission Mode (RVA 0x7178 / 0x71b8) sit in the boot/verify cluster, and the RAM-boot path re-enters the same LoadImageAndAuthBootLinux pipeline (AVB enforcement code path (LoadImageAndAuth / libavb), Kernel/DTB/ramdisk load and the kernel hand-off) on the downloaded buffer rather than a flashed partition, subject to the same lock-state AVB gate.

2.5.6. Provenance

Source:

../artifacts/abl_a/abl_dxe_fv.bin (RVA 0x32888 CmdDownload; FastbootLib cluster 0x2d1200x3043c incl. FastbootInitialize / getvar publishers 0x2fe3c / 0x30518; partition/LUN 0x21db0 / 0x230c8; getvar dispatcher 0x325dc). Structural correlation against QcomModulePkg/Library/FastbootLib/FastbootCmds.c / FastbootMain.c at CodeLinaro tag LA.UM.9.12.1.r2-05100-SMxx50.QSSI12.0 (QSSI12; version gap is an open question — ABL function map and upstream-source correlation, Open questions and limits of analysis).

Method:

handlers located by embedded debug/error strings (AArch64 adrp/add literals resolved with Capstone); the FastbootRegister linked-list registration and the download/DataReady transport read from FastbootCmds.c / FastbootMain.c and matched to the binary cluster. The flash/erase string divergence was established by confirming the QSSI12 guard strings are absent from the binary’s full string table while the flash/erase/erase-block machinery is present. radare2 merges most of FastbootLib into a few large functions; per-command decomposition follows the source.

Cross-refs:

ABL overview, key handling, fastboot (command surface, cmd_list, no unlock), AVB enforcement code path (LoadImageAndAuth / libavb) (lock state, RAM-boot AVB gate), Kernel/DTB/ramdisk load and the kernel hand-off (boot pipeline), ABL entry point and top-level orchestration (FastbootInitialize entry), ABL function map and upstream-source correlation (function inventory, deviations table).