6.1. Secure world and coprocessors (TZ, HYP, trustlets)¶
Structural reverse engineering of the images PIL loads beside and below the
HLOS: the TrustZone secure monitor (tz_a), the hypervisor (hyp_a), the TZ
device config (devcfg_a), the QSEE trustlets (keymaster, uefisecapp,
featenabler, mdtpsecapp), and the two service coprocessors (aop_a,
qupfw_a). The exception-level narrative and where these sit in the boot
order is in Boot chain and exception-level hand-off (PBL → XBL → ABL); this page is the per-image evidence — ELF
container, load geometry, and the disassembly that pins each one to its exception
level or processor. The ADSP/CDSP DSPs are a separate subsystem in
ADSP and CDSP firmware; the signing envelope common to all of these is in
Secure boot and image signing.
Every image below is an MBN/ELF whose PH0 is the Qualcomm hash-table segment
(p_flags top byte 0x07) and whose second PT_NULL (0x02200000)
carries the signature + certificate chain. On this unit that chain is the public
Qualcomm test key throughout (Generated Test Root CA / General Use Test
Key (for testing only) / SecTools Test User; attestation root QSEE
Attestation Root CA 4 SubCA 10) — identical to XBL/ABL (Secure boot and image signing).
6.1.1. Exception-level / processor map¶
Image |
ELF |
Entry |
Runs at |
Evidence |
|---|---|---|---|---|
|
AArch64 |
|
EL3 resident monitor |
entry writes |
|
AArch64 |
|
EL2 hypervisor |
entry writes |
|
AArch64 |
|
EL3 data (TZ) |
all-RW segments, no code; config namespace consumed by TZ |
|
AArch64 |
(reloc) |
EL1 secure (QSEE app) |
|
|
ARM32 |
(reloc) |
EL1 secure (QSEE app) |
descriptor |
|
AArch64 |
(reloc) |
EL1 secure (QSEE app) |
MBN |
|
— (blank) |
— |
EL1 secure (QSEE app) |
partition all-zero on this unit (MDTP not provisioned) |
|
ARM32 (Thumb) |
|
Cortex-M (Always-On) |
Thumb entry ( |
|
Hexagon (QDSP6) |
|
QUPv3 micro-DSP |
|
6.1.2. TZ — tz_a (QSEE, EL3 resident monitor)¶
tz_a.bin is a 4 MB AArch64 ELF, entry ``0x14680000``, 23 program headers.
It loads in two disjoint regions:
an EL3 monitor stub in IMEM — executable at
0x14680000(0xc034) and0x14690000(0x1818), immediately adjacent to XBL’s own IMEM footprint (0x146xxxxx); andthe QSEE secure OS in the ``0x1c00_0000`` window — executable segments at
0x1c00e000,0x1c032000,0x1c301000,0x1c35d000plus large RW data/heap segments spanning0x1c019000–0x1c3d4000(~3.5 MB).
The entry establishes an EL3 environment — disassembly at 0x14680000:
0x14680000: msr tpidr_el0, x0
0x14680004: msr tpidr_el1, x1
0x14680020: mov x0, #0xe00
0x14680024: msr scr_el3, x0 ; Secure Config Register (NS handling)
0x14680028: isb
0x1468002c: mov x0, #0x1c0
0x14680030: msr daif, x0 ; mask D/A/I/F
0x14680034: mrs x0, sctlr_el3
0x14680040: msr sctlr_el3, x0 ; MMU/cache control at EL3
0x14680064: mrs x0, cntpct_el0
0x14680068: mrs x1, mpidr_el1 ; per-CPU affinity → boot vs secondary
Writing SCR_EL3 and SCTLR_EL3 is only possible at EL3. This is the
resident secure monitor: after XBL’s PILDxe loads and authenticates it
(Boot chain and exception-level hand-off (PBL → XBL → ABL)), TZ takes ownership of EL3 from the XBL “Sec”
monitor (The EL3 “Sec” monitor and the EL1 hand-off) and owns it for the rest of runtime —
every SMC from the kernel, ABL, or the hypervisor lands here. The SCR value
0xe00 matches the value XBL Sec programs, i.e. the same secure-monitor
configuration is carried across the hand-off.
Version TZ.XF.5.10-00304-1, variant SAJAANAAA (Onyx Boox Note Air5 C (Qualcomm SM6350)).
6.1.3. HYP — hyp_a (QHEE, EL2 hypervisor)¶
hyp_a.bin is a 512 KB AArch64 ELF, entry ``0x8004a000``, one RWX load
segment at 0x8004a000 (file 0x60e08, reserving 0x23f000 ≈ 2.3 MB). The
entry establishes an EL2 environment — disassembly:
0x8004a000: bl … bl ; PC-relative reloc trampoline (chained bl)
0x8004a048: msr vbar_el2, x4 ; EL2 vector base
0x8004a04c: mrs x3, vmpidr_el2
0x8004a08c: msr mair_el2, x4 ; EL2 memory attributes
0x8004a090: mrs x4, id_aa64pfr1_el1
VBAR_EL2 / MAIR_EL2 / VMPIDR_EL2 are EL2-only. This is the Qualcomm
hypervisor (QHEE): it installs itself at EL2, which is why the Linux kernel on
this SoC is entered at EL1, never EL2 (Boot chain and exception-level hand-off (PBL → XBL → ABL)). Its string
set shows a “hyp manager” that brokers SMC traffic to trustlets — e.g.
hyp_manager_lookup_mssecapp_id / qcom.tz.mssecapp (the modem secure app).
HYP is built from the same package as TZ (version TZ.XF.5.10-00304-1).
After the reloc trampoline the init path (0x8004a044) sets VBAR_EL2 =
0x80090000, lays out a per-CPU stack (sp = 0x801f5000 − 0x2000·affinity,
the affinity taken from VMPIDR_EL2), programs MAIR_EL2, probes
ID_AA64PFR1_EL1 for MTE, brings up the EL2 stage-1 MMU (TTBR0_EL2 /
TCR_EL2 / SCTLR_EL2 = 0x8100f = M|A|C|SA|I|WXN) and sets CNTHCTL_EL2 =
3 so EL1 keeps the physical counter/timer.
6.1.3.1. The EL2 vector table¶
VBAR_EL2 points at a standard 16-entry AArch64 vector table at 0x80090000
(0x80 stride) — QHEE’s primary EL2 dispatch table. The twelve IRQ / FIQ /
SError slots are stubs that push x30/x0, load a numeric exception index
(0x9–0x17) and tail-call a common handler at 0x8004f638; the four
Sync slots have real handlers:
+0x000 Sync EL2t -> b 0x8004a400
+0x200 Sync EL2h -> b 0x8004b004
+0x400 Sync lower A64 -> HLOS trap dispatch (below) <- the kernel's gate
+0x600 Sync lower A32 -> same shape as +0x400
+0x080..+0x780 IRQ/FIQ/SError (EL2t/EL2h/lowerA64/lowerA32)
-> mov x0,#{9..0x17}; bl 0x8004f638 (common sink)
6.1.3.2. HLOS trap dispatch and stage-2 protection¶
The lower-EL AArch64 Sync entry (0x80090400) is where the EL1 kernel traps
into the hypervisor. It reads the VMPIDR_EL2 affinity, indexes a per-CPU
byte table (0x801cbed0) for a short settle/erratum spin, dsb nsh; isb,
then decodes ESR_EL2.EC:
EC 0x17 SMC (AArch64) -> 0x8004a468 (SMC service path)
EC 0x20 Instruction Abort, lower -> 0x8004ac38 (stage-2 IABT)
EC 0x24 Data Abort, lower -> 0x8004adcc (stage-2 DABT)
EC 0x18 trapped MSR/MRS (A64) -> 0x8004b19c
EC 0x03 trapped MCR/MRC CP15 (A32) -> 0x8004b19c
else (incl. HVC EC 0x16) -> 0x8004ad0c
The stage-2 abort handler (0x8004ac38) saves the full GPR frame, re-reads
ESR_EL2, checks the ISS fault-status, reads FAR_EL2 (the faulting IPA) and
calls a registered handler pointer at [0x8004b408] with the address — this
is QHEE’s stage-2 memory-protection check on HLOS accesses. The stage-2 role is
confirmed by the string set: AC_VM_HYP (an access-control VM), hyp_enable_dvm
(distributed virtual memory), hyp_ipa_based_safe_eco_swa,
hyp_secure_mor_PIL_start, the HypXVersion / HypXCodeAddr / HypXSize
metadata and a /dev/hyp diag node, plus the “Failed to … Hypervisor … HLOS
Stage 2” fault strings. Full disassembly in artifacts/re_static/item1_aop_hyp.txt.
6.1.4. TZ device config — devcfg_a¶
devcfg_a.bin (128 KB, AArch64 ELF, entry 0x1c003000) is data, not
code — its two load segments are RW only, placed at 0x1c003000 (adjacent
to QSEE) and 0x805fd000. The payload is a pointer-linked config blob (a DAL
“config-DB” structure, not a flattened DTB — no d00dfeed magic) whose
node namespace is TZ’s view of the hardware:
Node |
Role |
|---|---|
|
access-control: secure heap, SMMU, and XPU (memory-protection) config |
|
bus/DMA devices TZ owns (QUP access-control, GPI DMA engine) |
|
the TLMM pin configurations TZ reserves |
|
OEM TZ knobs and PMIC access |
|
OEM hypervisor config handed to HYP |
|
DDR-subsystem and NoC error-reporting policy |
It also carries the secure-storage path ACL (/data/vendor/tzstorage/,
/mnt/vendor/persist/data/, /data/misc/qsee/) and references trustlet app
IDs it gates (qcom.tz.hdcp2p2, qcom.tz.tpm). devcfg is not read-only
in the GPT (Partition map and checksums) — it is an updatable per-board config.
6.1.5. QSEE trustlets¶
The trustlets are ELF ``DYN`` (position-independent) objects that TZ loads
into the secure EL1 app space on demand, each authenticated by its own MBN
hash+signature (test key). They are addressed by name (qcom.tz.<app>):
Trustlet |
ISA |
Code size |
App ID |
Purpose (from strings) |
|---|---|---|---|---|
|
AArch64 |
|
|
Keymaster/KeyMint — key attestation ( |
|
ARM32 |
|
|
UEFI’s secure-service peer (secure storage / RPMB / fuse access during
boot); descriptor |
|
AArch64 |
|
|
SoC feature-enable (fuse-gated capability enablement) |
|
— |
blank |
|
Mobile Device Theft Protection — partition all-zero here (not provisioned) |
The keymaster PH3 carries the 0x04000006 “pointer/relocation” segment flag
characteristic of a QSEE DYN app. uefisecapp being 32-bit while
keymaster/featenabler are 64-bit reflects Qualcomm’s mixed QSEE ABI — the
UEFI-era app predates the 64-bit trustlet ABI. mssecapp (modem secure app,
brokered by HYP above) has no standalone partition — it is bundled with the modem
(ADSP and CDSP firmware).
6.1.5.1. Keymaster/KeyMint trustlet — command interface¶
The keymaster_a app (descriptor n=keymaster64;o=100;p=8:…, HAL
keymaster@4.1-service-qti) is the device’s root key store and attestation
authority. Its command dispatcher and internals are recovered from the app’s
string table (code segment file offset 0x3000, filesz 0x3584f); the full
extraction is in artifacts/re_static/item2_keymaster_interface.txt.
Command set. A legacy Keymaster-4 command enum (29 ids:
GENERATE_KEY/GET_KEY_CHARACTERISTICS/IMPORT_KEY/EXPORT_KEY/DELETE_KEY/DELETE_ALL_KEYS/BEGIN/UPDATE/FINISH/ATTEST/GET_VERSION/SET_ROT/IMPORT_WRAPPED_KEY/GET_HMAC_SHARING_PARAMS/COMPUTE_SHARING_HMAC/PROVISION_DEVICE_IDS…) and a newer KeyMintKM_NEW_*enum (61 ids) that addsKM_NEW_CONFIGURE/KM_NEW_VERIFY_AUTHORIZATION/KM_NEW_SET_EARLY_BOOT_ENDED/KM_NEW_GET_PRE_SHARED_SECRETand a parallel StrongBox…_SB_*sub-family (SB_GENERATE_KEY/SB_WRAP/SB_UNWRAP/SB_ATTEST_ENCRYPTED…). So one TA services both the KM4 HAL and the KeyMint path.Gatekeeper is integrated here, not a separate trustlet:
gk_generate_user_key/gk_wrap_key/gk_unwrap_key/gk_update_km_auth_list/gk_storage_init/open_add_km_partition. (The Android side still exposes a separategatekeeper@1.0-service-qtiHAL, but it is backed by this TA.)Crypto suite: AES, 3DES, HMAC, RSA and ECC, each with the
*_generate/_begin/_update/_finish/_import/_exportverb set, implemented over the QSEEqsee_SW_*/qsee_rsa_*syscall primitives.Attestation: the TA references the paths
/persist/data/rsa_attest_keyand/persist/data/ecc_attest_key, but on this unit no such plaintext files exist in thepersistbackup —/persist/data/instead holds QSEE secure-storage (SFS) blob directories (obfuscated base64url names, live +.bakpairs), so any provisioned attestation key is inside encrypted secure storage, not on disk in the clear (Partition map and checksums). Provisioning tooling ships in/vendor(bin/KmInstallKeybox,bin/StoreKeybox,libkeymasterprovision.so). Device-ID attestation coversATTESTATION_ID_{BRAND,DEVICE,PRODUCT,SERIAL,IMEI,MEID,MANUFACTURER,MODEL}; X.509 leaf certs are built in-TA (write_attestation_cert/sign_rsa_tbscert). Android Identity Credential keys are supported.Root of trust & HW binding.
SET_ROT/km_set_boot_state/km_set_vbhreceive the verified-boot state from ABL (AVB enforcement code path (LoadImageAndAuth / libavb));KM_ERROR_ROOT_OF_TRUST_ALREADY_SETenforces write-once. Working keys are derived from a SHK (Secure Hardware Key) with per-purpose context strings (KM/GK/UNIQUEID/DEVICEID/FILENAME/ICE“HW Crypto key derived from SHK”). TheICEcontext andSET_ICE_KEY/KM_TAG_FBE_ICEtie the TA to the inline-crypto FBE path (Security and DRM userspace). Key-blob rollback protection uses RPMB.
6.1.5.2. Keymaster/uefisecapp: function-level disassembly¶
The command-interface RE above (item2_keymaster_interface.txt) stopped at
the string/command-enum level. This section goes one level deeper — actual
instruction-level disassembly of keymaster_a.bin (AArch64) and
uefisecapp_a.bin (ARM32/Thumb-2), looking for the real crypto primitives,
the QSEE command-buffer marshalling, and the top-level SMC/command dispatch
shape, the same way The EL3 “Sec” monitor and the EL1 hand-off pins XBL’s SMC dispatch table. Full
raw disassembly and methodology: artifacts/re_static/item_tz_trustlet_funcs.txt.
Both images turn out to have a full dynamic symbol table (DT_SYMTAB/
DT_STRTAB/DT_HASH via PT_DYNAMIC) despite e_shnum == 0 (no
section headers) — unlike the kernel Image, which has no kallsyms
table at all and had to be symbolized by string/xref heuristics instead
(E-ink driver internals (register-level, from the kernel)), these QSEE apps are not fully
stripped once you walk the hash chain by hand (no pyelftools/lief/
readelf equivalent ships in this toolchain, so a small
DT_HASH walker was used). That recovers, for each file,
every imported syscall/library call by name and every locally-defined
function.
keymaster_a.bin exports exactly one local function beyond its GP-TA
metadata blob — CElfFile_invoke (file vaddr 0x2bd28, 0x314 bytes)
— and imports 69 functions from libcmnlib.so (DT_NEEDED): the
entire qsee_SW_Cipher*/qsee_SW_Hash*/qsee_SW_Hmac*/
qsee_SW_GENERIC_ECC*/qsee_rsa_* crypto surface, plus
GPAppLib_{init,appInit,appShutdown,handleRequest} and
CApp_openSession — i.e. the entire GP-TA runtime and command router is
an external dependency, not code in this file. libcmnlib.so is not a
separate partition on this device (no lun0-5 file named *cmnlib*)
but its strings (cmnlib, cmnlib64, cmnlib_init, cmnlib_release)
are present, statically embedded, inside tz_a.bin — so Keymaster’s actual
per-command switch and its crypto implementation both live inside the
resident TZ image, not in the trustlet partition.
CElfFile_invoke disassembles as the standard Qualcomm QSEE GP-TA
registration shim, not a command dispatcher: gated on an internal
cmd == 0x1200 loader convention (unrelated to the KM4/KeyMint command
IDs), it zero-fills a 0xd8-byte “TA properties” struct from linker-provided
ta_* symbols (heap/stack address+size, app name, description, storage-file
limits, crypto-self-test flag), then calls cmnlib_init →
GPAppLib_appInit → (an empty, dead init_array walk — no C++ statics on
this build) → GPAppLib_init, logging any failure via qsee_log at every
step. The same shim, structurally identical (same {0,0xfffe,0xffff}/
cmd==0x1200 gate, same memset-then-cmnlib_init flow), is uefisecapp’s
CElfFile_invoke (0xc640, 0x288 bytes, with a smaller 0x68-byte
properties struct) — confirming it’s a shared per-TA-recompiled loader
convention, not bespoke code.
An automated census (every br/blr/indexed-load instruction across all
48,304 decoded instructions in keymaster_a.bin’s 0x3584f-byte code
segment) rules out a monolithic KM4/KeyMint command switch living in this
file at all: the largest jump table anywhere in the binary has 24 cases (part
of an unrelated internal QSEE-status-code-to-string helper at 0xd84c,
used by the qsee_log assertion call sites), there are only 41 blr
(indirect call) instructions total, and only 4 pointer-table-indexed loads
(one being the dead init_array walk above). The real per-command
KM4/KM_NEW_*/SB_* router is GPAppLib_handleRequest, which lives in
cmnlib inside tz_a.bin — that dispatch table was not decoded here;
decoding it is a larger reverse-engineering task against the 4 MB TZ image.
Crypto primitives — not found to be implemented in either trustlet. Per
the task of looking for recognizable constants: a byte-exact scan for the AES
forward S-box and the SHA-256 round-constant table finds neither in
keymaster_a.bin nor uefisecapp_a.bin — but finds both, byte-exact,
plus the SHA-1 initial-hash constant, inside tz_a.bin. Every
qsee_SW_Cipher*/qsee_SW_Hash*/qsee_rsa_* call in both trustlets is
a real external call into that TZ-resident crypto core; a custom secure
monitor replicating this device’s Keymaster crypto surface would need to
reimplement (or re-host) code from tz_a.bin, not from either app image.
uefisecapp_a.bin is a different story: 306 dynamic symbols, ~200
locally defined — it statically links its own UEFI authenticated-variable
service, X.509 parser, PKCS7 verifier, and a bignum/RSA library (only the
actual modular-exponentiation primitive, _secmath_BIGINT_modexp, is
imported from cmnlib — everything else, pbl_BIGINT_{Add,Subtract,
Multiply,Divide,Square,ModMult,ModExp,...}, is local code, unlike
keymaster’s zero local crypto). This directly answers the “what does
uefisecapp back” question: TzGetVariable/TzSetVariable/
TzGetNextVariableName/TzQueryVariableInfo/TzDelSecBootVar/
TzSyncVarTables/TzVariableInitialize plus a full
TzVariablePolicy{Initialize,Register,Lock,Check,Disable,Dump,IsEnabled,
ExitBootServices,IsPrivAuthVarProtectionDisabled,IsSecureBootDisabled}
family, backing the PK/KEK/db/dbx UEFI Secure Boot variable store
(VariableName{PK,KEK,DB,DBX,SecureBoot,SetupMode},
SetupModeEnabled/SecureBootEnabled) — this is the fastboot-lock/AVB/
UEFI-secure-variable backing service on this device. It also carries
gen_key_for_rpmb/
register_pkkey/register_kekkeys for RPMB-backed key material.
Unlike keymaster, uefisecapp’s top-level command dispatcher lives inside
the TA itself and was fully located: ``svc_uefi_var_entry``
(file vaddr 0x588 — dynsym value 0x589 with the Thumb bit set, 0x838
bytes, the largest structural find in this file). Its dispatch core:
0x5d8 ldr.w r0, [sb] ; r0 = caller's UEFI command ID
0x5dc sub.w r0, r0, #0x8000 ; command space is 0x8000-based
0x5e0 cmp r0, #0x18
0x5e2 bhi.w #0xc90 ; out of range -> shared "other" block
0x5e6 tbh [pc, r0, lsl #1] ; Thumb-2 table-branch-halfword,
; 25 cases (cmd 0x8000-0x8018)
Decoding the halfword table directly from the file bytes and resolving every
case body’s bl target against the recovered dynamic-symbol table gives a
concrete command-ID → implementation map — an SMC/QSEE dispatch loop shaped
like XBL’s, but one level up the secure-world stack and keyed by
UEFI-variable-service command rather than XBL SiP function ID:
Command |
Resolved handler |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
converge on a shared block ( |
The remaining slots (0x8002, 0x8006, 0x800d, 0x800e,
0x8014, 0x8016, 0x8018) were confirmed to share the same
parameter-validation preamble as every resolved case but their specific
Tz* callee was not pinned down — see Honest limits. A sibling function,
svc_uefi_auth_entry (0xc484, 0x198 bytes, next to the PKCS7/X.509
verification code), is inferred — based on its name and location — to be the
authenticated-variable-update (EFI_VARIABLE_AUTHENTICATION_2 / db-dbx
signed-update) entry point; this is unconfirmed, as it was not disassembled.
6.1.5.2.1. Honest limits¶
keymaster_a.bin: only its single exported function (CElfFile_invoke) was function-by-function disassembled; the ~35 KB of code implementing the actual per-command KM4/KeyMint crypto/key-management logic has no local symbols to anchor on (this file exports exactly one) and was not walked instruction-by-instruction — the jump-table/indirect-call census (which rules out a dispatcher living here) stands in for full coverage, not full coverage itself. ~20 runs of consecutive function pointers were found in.datavia relocation analysis (plausible C++ vtables) but not decoded.uefisecapp_a.bin: 7 of 25 top-levelsvc_uefi_var_entrycommand slots are resolved directly, 7 more one level down through the shared0xc90block (14/25 effectively identified); the rest were traced structurally but not resolved to a named callee, andsvc_uefi_auth_entrywas located and sized but not disassembled at all. Neither TA’s RPMB key-derivation call target (insidegen_key_for_rpmb) was resolved to a name.No live-device tracing anywhere — purely static, cross-checked instruction-by-instruction against each file’s own recovered dynamic-symbol and relocation tables, plus a byte-exact constant scan against
tz_a.bin.
- Source:
artifacts/re_static/item_tz_trustlet_funcs.txt(full disassembly + methodology);_READONLY/lun4/{keymaster,uefisecapp,tz}_a.bin.- Method:
artifacts/re_static/mbn.py/elfdis.pyfor ELF layout and per-function Capstone disassembly (AArch64 for keymaster, Thumb-2 for uefisecapp — called per-region, not as one linear pass, which desyncs on Thumb: an odd/Thumb-bit-set vaddr passed straight through computes an off-by-one file offset and silently mis-disassembles, the same class of trap as the kernel funcmap nearest-symbol mis-snap); a hand-rolledDT_HASH/DT_SYMTAB/DT_JMPREL/DT_RELAwalker for dynamic-symbol and PLT/GOT/relocation recovery in the absence ofpyelftools/lief/readelf; a Capstone-based jump-table/indirect-call census script (ad hoc) for the keymaster negative result; a plain byte-exact scan for the AES-sbox/SHA-K constants.- Cross-refs:
The EL3 “Sec” monitor and the EL1 hand-off (the SMC-dispatch-table structural analogy), AVB enforcement code path (LoadImageAndAuth / libavb) (AVB/fastboot-lock consumer of uefisecapp’s UEFI-variable service).
6.1.6. Coprocessors — AOP and QUP¶
Two service processors are loaded early and outlive the OS boot:
- AOP —
aop_a(Always-On Processor, Cortex-M) 32-bit ARM ELF, Thumb entry. The AOP is the always-on micro-controller that runs RPMh / resource-state and low-power coordination for the SoC. Version
AOP.HO.2.0-00069. Full internals — addresses, the Cortex-M vector table, the RPMh ARC rails, the Cx-retention FSM, the DDR manager and the QMP/message-RAM channel — are in AOP — the Always-On Processor (RPMh / power back-end).- QUP —
qupfw_a(QUPv3 serial-engine firmware, Hexagon) Hexagon QDSP6 ELF (
e_machine= 164), 81 KB, nine paged code segments (segment flag0x08000007) loading from0x1000. This is the microcode the GENI/QUPv3 serial engines execute to implement I²C/SPI/UART protocols — the firmware side of the GENI hardware documented in QUP/GENI serial-engine bus map (what is wired where). The GENI engines are inert until XBL loads this image, so any bare-metal payload that wants QUP-backed I²C/SPI/UART inherits (or must re-load) it.
- Source:
_READONLY/lun4/{tz_a,hyp_a,devcfg_a,keymaster_a,uefisecapp_a, featenabler_a,mdtpsecapp_a,aop_a,qupfw_a}.bin— ELF program headers (mbn_dump.py), Capstone disassembly of thetz_a(0x14680000) andhyp_a(0x8004a000) entries (eldis.py), and image strings for versions / app IDs / cert chain.- Cross-refs:
Boot chain and exception-level hand-off (PBL → XBL → ABL), The EL3 “Sec” monitor and the EL1 hand-off, AOP — the Always-On Processor (RPMh / power back-end), Partition map and checksums, Onyx Boox Note Air5 C (Qualcomm SM6350), ADSP and CDSP firmware, Below UEFI — execution state and hardware register surface, Base kernel device tree (the SoC boot contract), Secure boot and image signing, AVB enforcement code path (LoadImageAndAuth / libavb).