==================================== ABL overview, key handling, fastboot ==================================== ``abl_a.bin`` is the Applications Bootloader for the Onyx Boox Note Air5 C: a Qualcomm-signed ELF32/ARM container carrying a UEFI Firmware Volume whose payload is the LinuxLoader UEFI application. It reads the power/volume buttons through the PMIC Power-On (PON) protocol, exposes a fastboot command table with no bootloader-unlock command, and enforces AVB (VB2) verified boot. Deep dives ========== This page is the ABL overview. The function-level reverse engineering of the DXE is split across dedicated pages: - :doc:`/abl/linuxloader` — PE entry, ``LinuxLoaderEntry`` orchestration, ``Board.c`` platform identification. - :doc:`/abl/bootlinux` — kernel/DTB/ramdisk load and the kernel hand-off contract (``UpdateCmdLine`` / ``UpdateDeviceTree``). - :doc:`/abl/verified-boot` — the AVB (``LoadImageAndAuth`` / libavb) enforcement code path, boot-state colours and menus. - :doc:`/abl/fastboot` — FastbootLib handler internals (download, getvar, flash/erase). - :doc:`/abl/function-map` — exhaustive reachable-function inventory, upstream-source correlation and the deviations table. - :doc:`/xbl/handoff` — how XBL locates, authenticates and launches this ABL. Container layout ================ Occupies a 1 MB partition; used bytes end at ``0x27000``. - ``PT_LOAD`` at file ``0x3000``, vaddr ``0x9fa00000``, size ``0x24000`` — a UEFI Firmware Volume whose ``EFI_FIRMWARE_VOLUME_HEADER`` starts at that same file offset, ``0x3000`` (``FileSystemGuid``, little-endian-parsed: ``8c8ce578-8a3d-4f1c-9935-896185c32dd3``, the well-known ``EFI_FIRMWARE_FILE_SYSTEM2_GUID``); the literal ``"_FVH"`` signature sits ``0x28`` bytes into the header, at ``0x3028``. - The FV holds one LZMA-compressed GUIDed section starting at ``0x3078``, which decompresses to 434,376 bytes (``../artifacts/abl_a/abl_dxe_fv.bin``). That blob is the ABL proper. - Inside it: the LinuxLoader UEFI application, PE32+ AARCH64, MZ at ``0xb8`` / PE at ``0xf10``, ``ImageBase=0``, sections ``.text`` (RVA ``0x1000``, size ``0x4d000``), ``.data`` (RVA ``0x4e000``), ``.reloc``. Because ``ImageBase=0`` and file raw offset equals RVA, the handler RVAs below are also file offsets into the DXE blob minus ``0xb8``. Build provenance ================ The image is a DEBUG build; full assert/log strings are present in a production ABL. The embedded debug path is:: /data/jenkins-agent/workspace/sm6350-15-REL/vendor/out/target/product/NoteAir5C/obj/ABL_OBJ/ Build/DEBUG_CLANG35/AARCH64/QcomModulePkg/Application/LinuxLoader/LinuxLoader/DEBUG/LinuxLoader.dll - SoC = SM6350 (Snapdragon 690 5G), codename "lagoon" — confirmed by the ``sm6350-…`` build path and DTB ``qcom,lagoon`` / ``msm-id 0x1b2`` (434). - ``DEBUG_CLANG35 / DEBUG`` build: full assert/log strings are present. Key handling ============ ABL uses no ``gpio-keys`` / GPIO scan table. It reads buttons through the Qualcomm PMIC Power-On (PON) protocol and decodes the PON reason. Evidence strings in the DXE: - ``PON Reason is 0x%x cold_boot[%d] PON1[%d] KPDPWR[%d] CBLPWR[%d] USB[%d] DC[%d] ChgPresent[%d].`` - ``Pressed down Power key[%d].``, ``Error locating pmic pon protocol: %r``, ``Error getting pon reason`` - Boot-mode selection is time/press based, not a static table: ``GetBootIntoModeRecovery … Power key Down/Up``, ``BootIntoDload detected``, ``BootIntoFastboot detected``, ``BootIntoRecovery detected``, ``Creating fastboot menu keys detect event``, ``Press volume key to select, and press power key to select``. The physical button map lives in the device tree (``../artifacts/boot_a/board.dts``), under the PMIC ``qcom,qpnp-power-on@800`` node: =============== ============== =================== ================= PON node pon-type ``linux,code`` Meaning =============== ============== =================== ================= ``qcom,pon_1`` 0 (KPDPWR) ``0x74`` = 116 KEY_POWER ``qcom,pon_2`` 1 (RESIN) ``0x72`` = 114 KEY_VOLUMEDOWN =============== ============== =================== ================= ``interrupt-names = "kpdpwr", "resin"``. The button matrix is Power (KPDPWR) + Volume-Down (RESIN); the recovery/fastboot/EDL entry combos are decoded in ABL from PON state plus press timing. No ``gpio-keys`` node and no separate Volume-Up PON entry appear in this DTB. Resolved key/timing handler addresses (RVA, LinuxLoader-relative): - ``0x1d9a8`` = ``ReadKeyStroke`` (``SimpleTextInputEx``) — produces the ``2``/``8``/``0x102`` scancodes. - ``0x2158`` = a ``gBS->Stall`` wrapper (100 ms/cycle debounce tick). - ``0x10708`` = reboot-into-EDL: sets UEFI var ``RESET_PARAM="EDL"`` then ``gRT->ResetSystem(EfiResetPlatformSpecific,"EDL")`` (strings ``RESET_PARAM``@``0x42e9a``, ``EDL``@``0x42eb2``). - ``0x2618`` / ``0x2640`` = debug-log-level gates (read a debug-config byte; guard every printf). The full boot-mode dispatch state machine built on top of these (the recovery 5-tap, dload/fastboot hold timers, ``g_mode_flags`` bit layout) is in :doc:`/boot/keys`, not repeated here. Fastboot command handlers ========================= Static command table (``cmd_list``) ----------------------------------- Located by pointer-scan at DXE file ``0x4b978`` (RVA ``0x4b8c0``); 16-byte entries ``{char *name; fn *handler}``. There are 14 real commands (the trailing ``none`` / ``snapshotted`` belong to an adjacent snapshot-merge-state array, not the command list): ==== ============================== ================ \# command handler RVA ==== ============================== ================ 0 ``oem enable-charger-screen`` ``0x31c18`` 1 ``oem disable-charger-screen`` ``0x31c70`` 2 ``oem off-mode-charge`` ``0x31cc8`` 3 ``oem select-display-panel`` ``0x31e38`` 4 ``oem device-info`` ``0x321bc`` 5 ``continue`` ``0x3228c`` 6 ``reboot`` ``0x3234c`` 7 ``reboot-recovery`` ``0x32388`` 8 ``reboot-fastboot`` ``0x323e0`` 9 ``snapshot-update`` ``0x32438`` 10 ``reboot-bootloader`` ``0x32598`` 11 ``getvar:`` ``0x325dc`` 12 ``download:`` ``0x32888`` 13 ``oem display-cmdline`` ``0x32a74`` ==== ============================== ================ Commands registered outside the static array --------------------------------------------- ``flash:``, ``erase:``, and ``boot`` are registered individually (not via the ``{name,handler}`` array), so they do not appear as table rows; their strings/paths are present in the image (``erase``, ``FLASH``, ``getvar:partition-type``, ``flashall`` handling, ``max-download-size``, ``partition-type:``, ``partition-size:``, ``slot-count``, ``has-slot:*``, ``current-slot``, ``is-userspace``, ``is-logical``, ``erase-block-size``, ``serialno``). No bootloader-unlock command is exposed --------------------------------------- - No ``flashing unlock`` / ``flashing lock`` / ``oem unlock`` / ``oem lock`` / ``get_unlock_ability`` command strings exist in this ABL. - Internal unlock plumbing is present but not reachable via fastboot: ``IsAllowUnlock is %d``, ``Creating unlock keys detect event``, ``Failed to update the unlock status: %r``. - The standard ``fastboot flashing unlock`` path is stripped/disabled by the vendor. Combined with ``devinfo`` ``is_unlocked=0``, there is no advertised fastboot path to unlock — independent of the test-key-signing condition below. Verified-boot enforcement ========================= ABL implements AVB (VB2) and sets device state: ``androidboot.verifiedbootstate=``, boot states ``green`` / ``orange`` / …, ``Verity mode: %a``, ``ignore_corruption`` / ``restart_on_corruption``, ``SetVerifiedBootHash``, ``Your device is corrupt. It can't be trusted and will not boot.``, ``State: Unlocked, AvbSlotVerify returned %a, continue boot``. AVB is enforced here, but this ABL binary is test-key-signed and unfused (:doc:`/boot/secure-boot`); whether a re-signed, patched ABL would perform that enforcement just as easily has not been empirically verified here by flashing a patched image. Provenance ========== :Source: ``../_READONLY/lun4/abl_a.bin`` (read-only); decompressed DXE saved to ``../artifacts/abl_a/abl_dxe_fv.bin``. :Method: ELF/FV parsed by hand; LZMA GUIDed section decompressed with Python ``lzma``. LinuxLoader PE parsed (PE32+/AARCH64, ImageBase 0, raw==RVA). ``cmd_list`` found by scanning the blob for 8-byte LE pointers equal to command-string VAs; the following qword in each 16-byte record is the handler RVA (all land in ``.text``). Key handling read from DXE strings and the DTB ``qcom,qpnp-power-on`` node. Handler RVAs validated by pointer-scan of the LinuxLoader PE. :Cross-refs: :doc:`/boot/secure-boot` (test-key signing, unlock state), :doc:`/boot/keys` (boot-mode state machine), ``../artifacts/abl_a/abl_dxe_fv.bin`` (decompressed ABL UEFI FV/DXE), ``../artifacts/boot_a/board.dts`` (PMIC PON node).