1.2.1. XBL → ABL hand-off contract (bounded)¶
This page answers exactly four questions about how XBL locates, authenticates, and hands control to ABL, and what execution environment ABL inherits. It is not a full XBL reverse engineering: DDR training, PMIC sequencing, clock trees and the rest of the XBL/SBL loader are not covered here — a from-scratch ABL replacement does not require modifying XBL. Only the hand-off surface an ABL replacement must satisfy is covered. This page takes the UEFI/DXE-protocol view; the same hand-off at the register level — exception level, MMU/cache state, and the bare addresses/IRQs/clocks/pins of the SoC blocks below the OS — is in Below UEFI — execution state and hardware register surface.
xbl_a.bin is an AArch64 ELF EXEC (entry 0x14817908, 16 program
headers). The XBLCore/Sec loader occupies the R E LOAD segment at vaddr
0x14817000 (file 0x3000); the UEFI firmware volume (DxeCore + drivers +
the embedded platform config) is the large segment at vaddr 0x9fc00000 (file
0x7e7a0). Citations below give the file offset and, where it maps cleanly,
the loaded vaddr. The build is BOOT.XF.3.3-00340 / XBLCore Sec.dll
(Onyx Boox Note Air5 C (Qualcomm SM6350)).
1.2.1.1. Q1 — Dispatch mechanism (named BDS boot app, not generic FV scan)¶
XBL does not generically dispatch “any valid FV/FFS/PE it finds”. It runs a platform BDS (Boot Device Selection) that launches one named boot application:
Loading DxeCore at 0x%10p EntryPoint=0x%10p/DxeCore returned(file0xa912f, UEFI-FD segment ≈ vaddr0x9fc2a98f) — XBLCore loads and enters the standard EDK2 DxeCore, which runs the DXE dispatcher and then BDS.The embedded platform config carries
## Default app to boot in platform BDS init→DefaultBDSBootApp = "LinuxLoader"(file0xbaf0c≈ vaddr0x9fc3c76c). BDS launches the application whose name isLinuxLoader— i.e. a targeted launch of a specific app, configured by name, not a blind scan that executes whatever FV happens to be present.The ABL image is placed in a dedicated reserved region,
"ABOOT FV"at0x9FA00000(size0x200000; memory-map entry at file0xb8c79), which matches the ABLPT_LOADvaddr0x9fa00000in ABL overview, key handling, fastboot. XBL loads theablpartition (a Qualcomm-signed ELF, ABL overview, key handling, fastboot) into this region, then BDS/DxeCore starts theLinuxLoaderapplication from it — which isModuleEntryPointat RVA0x1000(ABL entry point and top-level orchestration).
So the chain is: XBLCore → DxeCore dispatcher → platform BDS → StartImage of
the named “LinuxLoader” app in the reserved ABOOT FV. An ABL replacement
must present itself as the LinuxLoader boot app in that FV, not merely be
a valid PE somewhere.
The dispatch is by name, and both ends are recovered — not from the
section-stripped XBLCore image, but from ABL’s own container. Parsing
abl_a.bin (ELF32 → outer FV, EFI_FIRMWARE_FILE_SYSTEM2 GUID
8c8ce578-8a3d-4f1c-9935-896185c32dd3) → the single FIRMWARE_VOLUME_IMAGE
FFS → its LZMA (ee4e5898-3914-4259-9d6e-dc7bd79403cf) GUIDed section
decompresses (434,376 bytes) to the inner DXE FV, which contains exactly one
application file:
FFS type
0x09(EFI_FV_FILETYPE_APPLICATION), GUIDf536d559-459f-48fa-8bbc-43b554ecae8d, carrying aEFI_SECTION_USER_INTERFACE(type0x15) section with the UI name “LinuxLoader”.
The config token stores the app as the string "LinuxLoader" (not a GUID),
and the FFS carries a matching UI-section name — so BDS resolves the boot app by
its UI name, not by a hard-coded file GUID. A replacement therefore only needs
to be an EFI_FV_FILETYPE_APPLICATION file whose UI section reads
LinuxLoader, packaged in the ABOOT FV; carrying the same file GUID
f536d559-… is harmless but not required for name-based dispatch. (The
mechanism — named-app launch, not generic dispatch — remains what the config
token, the DxeCore/BDS load path, and the dedicated ABOOT FV region establish.)
1.2.1.2. Q2 — ABL authentication (ELF hash-segment, SHA-384)¶
XBL authenticates abl_a.bin with the same MBN/ELF hash-segment
mechanism that PBL uses on XBL (Secure boot and image signing), not a different or
stronger scheme:
The XBLCore code segment contains the Qualcomm boot-auth timestamp labels
bl_hash_seg_auth_timestamp(file0x6b0f≈ vaddr0x1481ab0f),bl_elf_segs_hash_verify_timestamp(file0x6b54≈ vaddr0x1481ab54) andbl_sec_hash_seg_auth_timestamp— the standard sequence that authenticates an image’s hash segment and then verifies each ELF loadable segment against the per-segment hashes in it.The per-segment hash is SHA-384 and the hash-segment signature chains to the same Qualcomm test attestation root carried by XBL/ABL/TZ — the string
XBL Sec Attestation Root CA 4(file0x2beb87≈ vaddr0x149503e7) andGenerated Test Attestation CAappear in XBL, matching the ECDSA-P384/SHA-384 test chain carved fromabl_ain Secure boot and image signing.
So XBL→ABL is hash-table (SHA-384) integrity plus a signature over the hash
segment, exactly the PBL→XBL pattern. As established in Secure boot and image signing,
on this unit the root of trust is the public Qualcomm test key and
SEC_BOOT is not fused, so re-computing the ABL hash segment (and re-signing
with the public test key) is accepted — the authentication is real but not
anchored to a secret. This page confirms the mechanism by direct evidence
rather than by analogy; the enforcement weakness is analysed in
Secure boot and image signing.
No nested / EL3 sub-image gate on this path. The Firehose programmer
container carries a nested EL3 monitor sub-image that PBL signature-enforces
unconditionally, regardless of SEC_BOOT (Firehose fuse read and secure-boot confirmation) — worth
ruling out for ABL, since it would defeat the hash-recompute route. It does not
apply: abl_a.bin is a single ELF/MBN (one ELF magic in the partition) — one
hash-table segment (PT_NULL, 0x94 bytes) plus the UEFI FV PT_LOAD at
0x9fa00000, with no embedded EL3 monitor, exception-vector table, or
smc/sec_img sub-container (the only QSEE string is a Keymaster call
reference in the LinuxLoader payload, not a loadable image). EL3 on this SoC is
tz_a, a separately-signed image loaded by PBL/SBL and never embedded in or
launched by ABL. So, based on this analysis, a from-scratch replacement faces
only the hash gate above.
1.2.1.3. Q3 — Protocols/services published by ABL-dispatch time¶
By the time BDS starts LinuxLoader, DxeCore has dispatched the platform’s
DXE drivers. The embedded platform config enumerates the enabled feature blocks,
and ABL’s own consumption (documented on the ABL/power pages) confirms the
producers are live:
Service (protocol) |
Evidence / consumer |
|---|---|
Block/partition I/O — |
Config blocks |
Keypad input — |
Config block |
PMIC Power-On — Pmic PON protocol |
|
USB device — QUSB/DWC3 for fastboot/EDL |
Config block |
Boot/Runtime Services + SMEM/DAL |
Standard EDK2 |
ABL therefore inherits a fully-initialised DXE environment: GPT partition access (BlockIo/PartitionDxe), keypad input (SimpleTextInputEx), PMIC PON, USB, display (splash), and live Boot/Runtime Services — it does not re-initialise these.
1.2.1.4. Q4 — Reserved memory carve-outs (from XBL’s own map)¶
XBL builds the UEFI memory map from an embedded platform table (header
#MemBase, MemSize, MemLabel(32 Char.), BuildHob, ResourceType,
ResourceAttribute, MemoryType, CacheAttributes at file 0xb890a ≈ vaddr
0x9fc3a16a). The reserved / carve-out regions an ABL replacement must
never overwrite, taken directly from that table (not inferred from the DTB):
Base |
Size |
Label |
Note |
|---|---|---|---|
|
|
|
AOP command DB (RPMh); reserved. |
|
|
|
Shared memory (inter-processor); reserved. |
|
|
|
344 MB Peripheral-Image-Loader carve-out — modem/ADSP ( |
|
|
|
AOP message RAM (device). |
|
|
|
XBL’s own FV, the ABL load region, and the UEFI firmware device. |
|
various |
|
XBL runtime working set and page tables. |
|
|
|
Framebuffer/splash region (Splash partition). |
|
|
|
Kernel load window (Kernel/DTB/ramdisk load and the kernel hand-off). |
Device MMIO windows (PMIC ARB SPMI 0x0C400000, TLMM 0x0F000000,
APSS_GIC* 0x17A00000, QTIMER 0x17C00000, USB, MDSS/DISP_CC, etc.)
are also in the table as MMAP_IO device regions.
Note
TZ/HYP are secure-world and not in this non-secure UEFI map. TrustZone and
the hypervisor are established by PBL/SBL before UEFI and sit in secure
carve-outs protected by XPU; they do not appear as entries in XBL’s non-secure
memory map above (which is why tz/hyp labels are absent here). Their
partitions are inventoried in Partition map and checksums and
Open questions and limits of analysis; the PIL Reserved block is the non-secure modem/DSP
carve-out.
1.2.1.5. Provenance¶
- Source:
../_READONLY/lun1/xbl_a.bin(read-only). File offsets:DefaultBDSBootApp0xbaf0c,ABOOT FV0xb8c79,PIL Reserved0xb8a8b, memory-map header0xb890a,bl_hash_seg_auth_timestamp0x6b0f,bl_elf_segs_hash_verify_timestamp0x6b54,Loading DxeCore at0xa912f,XBL Sec Attestation Root CA 40x2beb87. Loaded vaddrs derived from the ELF program headers (code segment file0x3000``→vaddr ``0x14817000; UEFI-FD segment file0x7e7a0``→vaddr ``0x9fc00000).- Method:
bounded string/constant analysis of
xbl_a.bin(rabin2/readelfprogram headers;strings+ byte-offsetgrepfor the config, memory-map table and boot-auth timestamp labels). Each of the four questions is answered from a concrete offset in the binary rather than inferred by analogy; the SHA-384/test-chain enforcement semantics are cross-checked against the certs carved in Secure boot and image signing. No full XBL disassembly was performed; the section-stripped XBLCore limits recovery of the exact FFS app GUID (Open questions and limits of analysis).- Cross-refs:
Secure boot and image signing (PBL→XBL hash gate, test-key chain), ABL overview, key handling, fastboot (ABL container, ABOOT FV vaddr), ABL entry point and top-level orchestration (
ModuleEntryPoint), Kernel/DTB/ramdisk load and the kernel hand-off (kernel window), Physical keys: power, volume, and the boot-mode dispatcher (ButtonsDxe/SimpleTextInputEx), Partition map and checksums, Onyx Boox Note Air5 C (Qualcomm SM6350), Open questions and limits of analysis.