diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e32d728 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Local development / bring-up backups +*.before-* +*.bak +*.orig +*.old +*.rej +*.tmp +*.swp +*~ + +# Editor / desktop junk +.DS_Store +Thumbs.db + +# Local scratch files +tab diff --git a/BoardConfig.mk b/BoardConfig.mk index cf944bb..660b595 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -94,9 +94,9 @@ TW_HAS_NO_RECOVERY_PARTITION := true BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE := true BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT := true BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT := true -# Optional A-Team dual-boot layout. -# Default: metadata / userdata -# DUALBOOT=Y: metadata2 / userdata2 +# Optional A-Team slotted dual-boot layout. +# Default: metadata / userdata without slot selection. +# DUALBOOT=Y: metadata / userdata use slotselect via recovery-dualboot.fstab. ifeq ($(strip $(DUALBOOT)),Y) TARGET_RECOVERY_FSTAB := $(DEVICE_PATH)/recovery-dualboot.fstab else @@ -110,6 +110,33 @@ endif # - present the exact production XT2575-4 vendor identity before Microtrust starts BOARD_RECOVERY_IMAGE_PREPARE = test -n "$(TARGET_RECOVERY_ROOT_OUT)" && \ rm -rf -- "$(TARGET_RECOVERY_ROOT_OUT)/lib/modules" && \ + if [ "$(strip $(NODECRYPT))" = "Y" ]; then \ + rm -f -- \ + "$(TARGET_RECOVERY_ROOT_OUT)/init.recovery.crypto.rc" \ + "$(TARGET_RECOVERY_ROOT_OUT)/system/bin/sycamore_keystore2_stage.sh" \ + "$(TARGET_RECOVERY_ROOT_OUT)/system/etc/init/zz_sycamore_keystore2.rc" \ + "$(TARGET_RECOVERY_ROOT_OUT)/system/etc/vintf/manifest.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/system/etc/vintf/manifest/android.system.keystore2-service.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/manifest.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/vintf/manifest/android.hardware.security.keymint-service.beanpod.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/vintf/manifest/android.hardware.security.secureclock-service.beanpod.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/vintf/manifest/android.hardware.security.sharedsecret-service.beanpod.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/vintf/manifest/android.hardware.gatekeeper@1.0-service.xml" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/bin/hw/android.hardware.security.keymint@2.0-service.beanpod" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/bin/hw/android.hardware.gatekeeper@1.0-service" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/bin/teei_daemon" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/hw/android.hardware.gatekeeper@1.0-impl.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/hw/gatekeeper.beanpod.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/hw/libSoftGatekeeper.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/android.hardware.security.keymint-V2-ndk.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/android.hardware.gatekeeper@1.0.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/libteei_daemon_vfs.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/lib_android_keymaster_keymint_utils.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/libkeymaster_messages.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/libkeymaster_portable.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/libkeymint.so" \ + "$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib64/libpuresoftkeymasterdevice.so"; \ + fi && \ sed -i \ -e 's/^ro.product.vendor.device=sycamore_row_5G$$/ro.product.vendor.device=XT2575-4/' \ -e 's/^ro.product.vendor.name=twrp_sycamore_row_5G$$/ro.product.vendor.name=XT2575-4/' \ @@ -150,12 +177,14 @@ TW_USB_STORAGE := false TW_EXCLUDE_APEX := true # Stock FBE v2 with metadata encryption. +ifneq ($(strip $(NODECRYPT)),Y) TW_INCLUDE_CRYPTO := true TW_INCLUDE_CRYPTO_FBE := true TW_INCLUDE_FBE_METADATA_DECRYPT := true +endif BOARD_USES_METADATA_PARTITION := true -# Bring-up/debug essentials; no missing-dependency escape hatch. +# Recovery utilities and diagnostics. TARGET_USES_LOGD := true TWRP_INCLUDE_LOGCAT := true TW_INCLUDE_REPACKTOOLS := true diff --git a/README.md b/README.md index 358f63c..c70b82a 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,149 @@ -Device configuration for Motorola Moto Pad 2026 (codenamed "sycamore_row_5G") -========================================= +# TWRP for Motorola Moto Pad 2026 -The Motorola Moto Pad 2026 / XT2575-4 (codenamed _"sycamore_row_5G"_) is an Android tablet from Motorola Mobility based on the MediaTek MT8755 platform. +Device tree for building Team Win Recovery Project for the Motorola Moto Pad 2026 / XT2575-4, codenamed `sycamore_row_5G`. -This device tree is intended for building Team Win Recovery Project (TWRP). +The device uses the MediaTek MT8755 SoC on the MT6835 Android platform and stores recovery in a version 4 `vendor_boot` image. ## Device specifications -Basic | Spec Sheet --------:|:------------------------- -Model | Motorola XT2575-4 -Codename | sycamore_row_5G -SoC | MediaTek MT8755 (MT6835 platform) -CPU | 64-bit ARM, Cortex-A76 / Cortex-A55 -GPU | ARM Mali -Shipped Android Version | Android 15 -Tested Stock Firmware | Android 16 / ZUI 17.5 -Storage | UFS -Display | 2560 x 1600 pixels, 90 Hz -Partition Scheme | A/B, Virtual A/B, Dynamic Partitions -Encryption | File-Based Encryption (FBE v2) with metadata encryption -Filesystem | F2FS userdata, EROFS/EXT4 dynamic partitions -Recovery Layout | TWRP recovery ramdisk stored in `vendor_boot` -Vendor Boot Header | Version 4 +| Component | Specification | +|---|---| +| Model | Motorola XT2575-4 | +| Codename | `sycamore_row_5G` | +| SoC | MediaTek MT8755 | +| Android platform | MT6835 | +| Architecture | ARM64 | +| CPU | Cortex-A76 / Cortex-A55 | +| GPU | ARM Mali | +| Shipping Android version | Android 15 | +| Tested firmware | Android 16 / ZUI 17.5 | +| Storage | UFS | +| Display | 2560 x 1600, 90 Hz | +| Partition scheme | A/B, Virtual A/B, dynamic partitions | +| Userdata | F2FS | +| Dynamic partitions | EROFS / EXT4 | +| Encryption | FBE v2 with metadata encryption | +| Recovery location | `vendor_boot` | +| Vendor boot header | Version 4 | -## Device picture +## Working -![Motorola Moto Pad (2026)](https://fdn2.gsmarena.com/vv/bigpic/motorola-moto-pad-2026-.jpg) +- Display and touch +- ADB +- Dynamic partitions +- A/B slot handling +- Fastbootd +- EROFS, F2FS and EXT4 +- exFAT and NTFS removable-storage support +- External SD card +- Stock PLATFORM vendor ramdisk preservation +- TWRP RECOVERY vendor ramdisk fragment +- Android 16 FBE v2 decryption +- Metadata encryption +- PIN/password protected userdata decryption +- Decrypted `/data/media` +- MediaTek / Microtrust TEE +- KeyMint +- Gatekeeper +- Keystore2 +- SELinux enforcing +- MTP +- Vibration +- Thermal sensor support + +## Validation remaining + +A final hardware-validation pass should cover: + +- Backup and restore using internal storage +- Backup and restore using removable storage +- ADB sideload +- ZIP flashing +- Image flashing from the TWRP UI +- Wipe and format operations +- Partition mount and backup lists +- USB-OTG devices +- Battery reporting +- Brightness control +- Date and time handling +- Screenshots +- Power-off and all reboot targets +- Advanced recovery functions + +## Building + +Place this tree at: + +```text +device/motorola/sycamore_row_5G +``` + +Build with: + +```bash +source build/envsetup.sh +lunch twrp_sycamore_row_5G-eng +m vendorbootimage -j$(nproc) +``` + +Output: + +```text +out/target/product/sycamore_row_5G/vendor_boot.img +``` + +`ALLOW_MISSING_DEPENDENCIES` is not required by this tree. + +## Dual-boot variant + +The normal build uses the standard `metadata` and `userdata` partitions. + +The optional A-Team dual-boot configuration keeps the canonical `metadata` and `userdata` block names, but enables `slotselect` for `/metadata` and `/data` and uses the matching dual-boot PLATFORM vendor ramdisk: + +```bash +export DUALBOOT=Y +source build/envsetup.sh +lunch twrp_sycamore_row_5G-eng +m vendorbootimage -j$(nproc) +``` + +Only use the dual-boot image on a device configured for the corresponding slotted dual-boot layout. + +## NODECRYPT development variant + +A recovery build without the device-specific crypto stack can be produced with: + +```bash +export NODECRYPT=Y +source build/envsetup.sh +lunch twrp_sycamore_row_5G-eng +m vendorbootimage -j$(nproc) +``` + +`NODECRYPT=Y` is intended for bring-up and troubleshooting. It omits the KeyMint, Gatekeeper, Keystore2 and Microtrust components required for normal userdata decryption. + +When switching between normal, `DUALBOOT=Y`, and `NODECRYPT=Y` configurations, clean the product output first to prevent artifacts from another configuration being reused. + +## Implementation notes + +Recovery is stored in `vendor_boot` using the Android vendor boot header version 4 layout. + +The stock PLATFORM vendor ramdisk is preserved rather than reconstructed. TWRP is supplied as the RECOVERY vendor ramdisk fragment. + +This preserves the production MediaTek module layout and early-boot environment while allowing TWRP to provide the recovery userspace. + +The tree also contains the device-specific components required for Android 16 FBE decryption through the MediaTek / Microtrust trusted execution environment. ## Device reference [Motorola Moto Pad (2026) - GSMArena](https://www.gsmarena.com/motorola_moto_pad_(2026)-14582.php) -# Status +## Credits -Current state of features: +- Team Win Recovery Project +- Motorola / Lenovo +- MediaTek +- A-Team Digital Solutions +- BOBtheBlinker -- Correct screen/recovery size -- Working touch and display -- ADB -- Support EROFS/F2FS/EXT4/exFAT/NTFS -- External SD card support -- Dynamic partition support -- A/B slot handling -- `vendor_boot` v4 support -- Stock PLATFORM vendor ramdisk preserved -- TWRP RECOVERY vendor ramdisk fragment -- Decrypt `/data` with user PIN/password -- Decrypted `/data/media` -- Metadata encryption -- KeyMint service -- Gatekeeper service -- Keystore2 service -- MediaTek/Microtrust TEE -- MTP export -- SELinux enforcing -- Vibrate and set vibration - -Still to validate before final release: - -- Backup/restore to/from internal/external storage and ADB -- ADB sideload -- Poweroff and all reboot targets -- Flashing zip/images from the TWRP UI -- All important partitions listed in wipe/mount/backup lists -- Input devices via USB-OTG -- Correct date/time configuration -- Battery level reporting -- Brightness adjustment -- Screenshot -- Advanced recovery features - -# Building - -```bash -export ALLOW_MISSING_DEPENDENCIES=true -source build/envsetup.sh -lunch twrp_sycamore_row_5G-eng -mka vendorbootimage -j$(nproc --all) -``` - -**Copyright (C) 2026 BOBtheBlinker | A-Team Digital Solutions** +Copyright (C) 2026 BOBtheBlinker / A-Team Digital Solutions diff --git a/VENDOR_BOOT_FRAGMENT_AUDIT.md b/VENDOR_BOOT_FRAGMENT_AUDIT.md deleted file mode 100644 index dcac022..0000000 --- a/VENDOR_BOOT_FRAGMENT_AUDIT.md +++ /dev/null @@ -1,112 +0,0 @@ -# Sycamore stock-vs-TWRP vendor_boot fragment audit - -Date: 2026-08-27 - -## Inputs - -- Factory: `/home/nicholas/Downloads/sycamore-twrp-info/vendor_boot_a.img` - - SHA-256: `e542af82e8bb153faa96a44ec480548b21ac99abf7ca26ffca0eafcc9b6a9fe` -- Hardware-tested V14: `/home/nicholas/Downloads/sycamore-twrp-info/first-hardware-boot/fbe-a16-v14-wrapped-first/vendor_boot.img` - - SHA-256: `d657365e5c14ba0bc1e93e9fc0ec38acb18f935e222d1bae66377011b96b9d15` -- Current untested output: `out/target/product/sycamore_row_5G/vendor_boot.img` - - SHA-256: `eb3388b6da20ce487976e40ff1a30ca8ee488680f01aeaaedb483e0aed555d18` - -All images are exactly 67,108,864 bytes. - -## Common header and retained sections - -The local AOSP `unpack_bootimg.py` reports these identical values for all three: - -- magic: `VNDRBOOT` -- header version: 4 -- header size: 2,128 -- page size: 4,096 -- kernel load address: `0x40000000` -- ramdisk load address: `0x66f00000` -- tags load address: `0x47c80000` -- DTB load address: `0x47c80000` -- vendor cmdline: `bootopt=64S3,32N2,64N2` -- product name: empty -- bootconfig: empty (0 bytes; SHA-256 of empty content - `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`) -- DTB: 192,119 bytes; SHA-256 - `0e93b71aacf707a5fbb7a58eff73995b92d766a31a98d8d70e91f548c9e1d5af` - -## Factory fragment table - -| Index | Name | Type | Table offset | Image offset | Compressed size | Compression | board_id | -|---:|---|---|---:|---:|---:|---|---| -| 0 | empty | PLATFORM (1) | 0 | 4,096 | 27,422,144 | LZ4 legacy | 16 zero words | - -Compressed payload SHA-256: -`06738f638a745075511c571347c5511331dda16b84d1ee88cda160c2dc7ebb14` - -Uncompressed CPIO: 67,875,584 bytes; SHA-256 -`cdf1d9fd1658989a4c198ca889802660f3a2d52a8fc527e40013c35da917642c` - -Factory total vendor ramdisk size is 27,422,144 bytes. Its table is 108 bytes -with one entry. There is no RECOVERY entry and no DLKM entry. - -## Hardware-tested V14 fragment table - -| Index | Name | Type | Table offset | Image offset | Compressed size | Compression | board_id | Compressed SHA-256 | Uncompressed size | Uncompressed SHA-256 | -|---:|---|---|---:|---:|---:|---|---|---|---:|---| -| 0 | empty | PLATFORM (1) | 0 | 4,096 | 27,422,144 | LZ4 legacy | 16 zero words | `06738f638a745075511c571347c5511331dda16b84d1ee88cda160c2dc7ebb14` | 67,875,584 | `cdf1d9fd1658989a4c198ca889802660f3a2d52a8fc527e40013c35da917642c` | -| 1 | `recovery` | RECOVERY (2) | 27,422,144 | 27,426,240 | 31,391,394 | LZ4 legacy | 16 zero words | `ae0c2ab5adba18a2a5bdaa79760b4d8aa474bd2de9f82ba25a1a343e6d810467` | 69,037,312 | `9c3945cd24333659f8aea5bc78a01bd5d9c4762603ad4a943be4cb62a874d01f` | - -Total vendor ramdisk size is 58,813,538 bytes. Its table is 216 bytes with -two entries, ordered PLATFORM then RECOVERY. - -## Current output fragment table - -| Index | Name | Type | Table offset | Image offset | Compressed size | Compression | board_id | Compressed SHA-256 | Uncompressed size | Uncompressed SHA-256 | -|---:|---|---|---:|---:|---:|---|---|---|---:|---| -| 0 | empty | PLATFORM (1) | 0 | 4,096 | 27,422,144 | LZ4 legacy | 16 zero words | `06738f638a745075511c571347c5511331dda16b84d1ee88cda160c2dc7ebb14` | 67,875,584 | `cdf1d9fd1658989a4c198ca889802660f3a2d52a8fc527e40013c35da917642c` | -| 1 | `recovery` | RECOVERY (2) | 27,422,144 | 27,426,240 | 31,677,990 | LZ4 legacy | 16 zero words | `b4e9de040d9d1c4e78a4fa8ab056a6bb7a42fafff6f99303f08fb43c54aa76ca` | 69,607,424 | `a1401628c4ca65d2fe1ab267e049d40c5e3a0c4d91187ad44d14b46808d2c001` | - -Total vendor ramdisk size is 59,100,134 bytes. Its table is 216 bytes with -two entries, ordered PLATFORM then RECOVERY. - -## Differential conclusion - -- **A. Stock multi-fragment:** NO. It has a valid v4 table but only one entry. -- **B. Stock PLATFORM:** entry 0, unnamed, type 1. -- **C. Stock RECOVERY:** none. Stock recovery content is contained in PLATFORM. -- **D. Stock PLATFORM preserved by TWRP:** YES, byte-for-byte in both V14 and - current output, for both compressed and uncompressed payloads. -- **E. Stock non-recovery fragment regenerated/replaced:** NO. PLATFORM is the - only stock fragment and is exact. Stock has no DLKM or other fragment. - -The hybrid principle is already implemented by -`tools/assemble_vendor_boot.sh`: the exact stock PLATFORM archive is entry 0 and -the generated TWRP ramdisk is appended as entry 1/RECOVERY. A new “hybrid” build -would not change this variable. PLATFORM preservation is therefore **PROVEN** -and is not a remaining explanation for the V14 cmd `0x18` failure. - -The required aggregate/table changes are limited to total ramdisk size, table -size/count, downstream aligned section positions, and the AVB hash/footer. -V14 and current output retain the stock DTB, cmdline, bootconfig, core header -values, fragment-0 metadata, and fragment-0 bytes. - -## Dynamic-partition corroboration - -Read-only live recovery inspection showed liblp/TWRP preparing logical -partitions from `super` and mapping: - -- `odm_dlkm_a` -> `dm-0` -- `product_a` -> `dm-1` -- `system_a` -> `dm-2` -- `system_b` -> `dm-3` -- `system_dlkm_a` -> `dm-4` -- `system_ext_a` -> `dm-5` -- `vendor_a` -> `dm-6` -- `vendor_dlkm_a` -> `dm-7` - -The active-slot convenience links resolve `system`, `system_ext`, `product`, -`vendor`, `vendor_dlkm`, `odm_dlkm`, and `system_dlkm` to those mapper nodes. -Any resulting `/dev/block/by-name/` links are runtime-created links to -`dm-*`, not physical GPT partitions. The existing `recovery.fstab` correctly -uses `logical,first_stage_mount`; no invented physical by-name paths are needed. - -No image was built, flashed, booted, or otherwise written to hardware during -this audit. diff --git a/bringup/investigations/vendor-boot-modules-load-collision.md b/bringup/investigations/vendor-boot-modules-load-collision.md deleted file mode 100644 index adbef38..0000000 --- a/bringup/investigations/vendor-boot-modules-load-collision.md +++ /dev/null @@ -1,139 +0,0 @@ -# Sycamore vendor_boot module-list pathname collision - -## Architecture - -Sycamore uses vendor_boot header v4. The device-specific assembler preserves the -factory Android 16 PLATFORM fragment byte-for-byte as table entry 0, then appends the -generated TWRP ramdisk as entry 1, type RECOVERY, named `recovery`. Both fragments use -legacy LZ4. PLATFORM contains the stock recovery/module infrastructure: all 203 `.ko` -files and `modules.alias`, `modules.dep`, `modules.load`, `modules.load.recovery`, and -`modules.softdep` under `/lib/modules`. - -The early device tree copied the five metadata files into TWRP's recovery root as -well. Consequently the RECOVERY archive contained duplicate canonical paths, despite -containing no `.ko` payloads. Because RECOVERY follows PLATFORM, a boot chain that -extracts both archives presents the later copy at those paths. - -## Isolation methodology and hardware evidence - -Compressed size, expanded size, compression ratio, payload data, entry count, and -general CPIO structure were separately controlled. A deterministic pathname-only -bisection retained neutral file payloads while restoring original V20.5 paths in -archive order. - -- `RESTORE-PREFIX-0029`: normal Android boot PASS -- `RESTORE-PREFIX-0030`: normal Android boot FAIL - -Those images differ only by restoring entry 30 to -`lib/modules/modules.dep`. Replacing its neutral 25,966-byte payload with the exact -stock dependency database produced `MODULES-DEP-STOCKPAYLOAD-CONTROL`, which PASSed. -This verifies that the canonical RECOVERY path reaches the normal first-stage module -consumer and that a valid payload removes the synthetic control failure. - -The real V20.5 PLATFORM and RECOVERY `modules.dep` are identical, so that file was -not the real-image cause. The actual differing metadata was `modules.load`: - -- stock normal: 179 entries, 3,020 bytes, SHA-256 - `1e9fe08beeb555147fbb39483f5fb4126046427bfa5432aa049cc4efa30b2f05` -- V20.5 RECOVERY: 199 entries, 3,351 bytes, SHA-256 - `1b61df29e9b0f9aef57fd5d7503779903f24fcf2a962d4f19bed166ae8b85d2b` - -The recovery list adds 24 modules and omits four relative to stock normal. Starting -from exact real V20.5 and replacing only the RECOVERY `modules.load` payload with the -stock normal payload produced `REAL-V20.5-STOCK-NORMAL-MODULES-LOAD`; normal Android -boot PASSed. - -## Conclusions - -**VERIFIED:** the differing RECOVERY `/lib/modules/modules.load` is sufficient to -cause real V20.5 normal-Android boot failure. - -**STRONG INFERENCE:** the later RECOVERY pathname shadows PLATFORM before normal -first-stage `libmodprobe` consumes `/lib/modules/modules.load`. - -**UNKNOWN:** the exact proprietary LK/vendor-ramdisk fragment selection or extraction -implementation that exposes a type-2 RECOVERY path during normal boot. - -## Implementation rationale - -The device assembler filters `lib/modules/**` only from the generated RECOVERY -archive. It does not modify the checked-out recovery staging tree, kernel modules, -generic TWRP/AOSP code, or the pristine PLATFORM fragment. PLATFORM remains the -single authoritative provider for both normal and recovery module metadata and all -203 module payloads. - -Hardcoding a second stock-normal `modules.load` in RECOVERY would repair the observed -collision but preserve unnecessary duplicate metadata and invite future drift. -Removing the duplicate RECOVERY tree instead preserves the factory pairing of module -payloads and metadata, including `modules.load.recovery` for recovery first stage. - -The canonical AOSP `m vendorbootimage` path does not invoke the standalone -`tools/assemble_vendor_boot.sh`. `BoardConfig.mk` therefore sets -`BOARD_RECOVERY_IMAGE_PREPARE` to remove the staged RECOVERY `lib/modules` directory -after device-root population and before `mkbootfs`. The standalone assembler applies -the same filter to its temporary archive root. Source prebuilts remain available for -forensics, while both assembly paths emit the same no-duplicate architecture. - -## Recovery runtime confirmation - -The hardware-validated `V20.5-NO-RECOVERY-LIB-MODULES` image booted TWRP. In that -running recovery, all five `/lib/modules` metadata hashes exactly matched pristine -PLATFORM: - -```text -modules.alias 47aa8d900c4bfe1a94f3fee6f405b5d674e33b806ac0fdbf02d17dc283f4ef55 -modules.dep 190915e985dc55ac4177914f17f5691eb486f0ae4891eca92b9cc8ee5f004fc4 -modules.load 1e9fe08beeb555147fbb39483f5fb4126046427bfa5432aa049cc4efa30b2f05 -modules.load.recovery f7a08319941624be65fcd12e7682b244dcdc7df079a7bf448415768e2641949e -modules.softdep 68b8d79bf7bdf36216f722f07ebc265fed0741025b376e3899b568dd31ecf641 -``` - -**VERIFIED:** with RECOVERY `lib/modules/**` absent, recovery receives the pristine -PLATFORM metadata; PLATFORM `modules.load.recovery` is visible in running TWRP; and -the PLATFORM module tree successfully serves both normal Android and recovery. - -## Canonical build integration - -The canonical `m vendorbootimage -j8` path was traced through -`build/make/core/Makefile`: device recovery files are copied into -`TARGET_RECOVERY_ROOT_OUT`, `BOARD_RECOVERY_IMAGE_PREPARE` runs, then `mkbootfs` and -legacy LZ4 create the RECOVERY fragment. The standard vendor_boot rule combines it -with `BOARD_PREBUILT_VENDOR_RAMDISK` and the DTB before adding AVB. - -The successful canonical build emitted no RECOVERY `lib/modules/**` paths and retained -the exact PLATFORM and DTB hashes. Its artifact SHA-256 is -`7aa012d093e53922cd97100d083f0ae5fc34ecbcbe5bdef4f84c67d11843d7d0`. - -## Final canonical hardware validation — CLOSED - -The canonical artifact booted both targets successfully: - -- normal Android: PASS; `sys.boot_completed=1` -- TWRP: PASS; ADB recovery, GUI/touch and storage functional -- effective `modules.load.recovery`: 197 lines -- `/proc/modules`: populated -- no `Failed to load kernel modules` -- no `Module .* not in dependency file` - -Runtime hashes of all five effective metadata files again exactly matched pristine -PLATFORM. - -Final classification: - -- **VERIFIED:** duplicate RECOVERY module metadata affected normal first-stage boot; - the differing RECOVERY `modules.load` was sufficient to cause V20.5's failure; - removing RECOVERY `lib/modules/**` restores normal boot; the canonical - `m vendorbootimage` integration works on hardware; recovery receives pristine - PLATFORM metadata and loads modules successfully; both Android and TWRP boot. -- **STRONG INFERENCE:** proprietary boot handling overlays or shadows later RECOVERY - paths over PLATFORM before first-stage `libmodprobe` consumes them. -- **UNKNOWN:** the exact proprietary LK implementation. - -**Investigation status: CLOSED.** Do not alter this implementation without new -contradictory evidence. - -Persistent detailed evidence: - -- `/home/nicholas/Downloads/sycamore-twrp-info/MODULES_DEP_NORMAL_BOOT_ANALYSIS.md` -- `/home/nicholas/Downloads/sycamore-twrp-info/MODULES_LOAD_NORMAL_BOOT_ANALYSIS.md` -- `/home/nicholas/Downloads/sycamore-twrp-info/normal-boot-name-controls/` diff --git a/device.mk b/device.mk index a835148..ebfb7c7 100644 --- a/device.mk +++ b/device.mk @@ -61,6 +61,7 @@ PRODUCT_COPY_FILES += \ $(DEVICE_PATH)/recovery/root/vendor/etc/vintf/manifest/android.hardware.security.sharedsecret-service.beanpod.xml:$(TARGET_COPY_OUT_RECOVERY)/root/vendor/etc/vintf/manifest/android.hardware.security.sharedsecret-service.beanpod.xml \ $(DEVICE_PATH)/recovery/root/vendor/etc/vintf/manifest/android.hardware.gatekeeper@1.0-service.xml:$(TARGET_COPY_OUT_RECOVERY)/root/vendor/etc/vintf/manifest/android.hardware.gatekeeper@1.0-service.xml +ifneq ($(strip $(NODECRYPT)),Y) PRODUCT_PACKAGES += \ sycamore_gatekeeper_impl \ sycamore_gatekeeper_hidl \ @@ -82,7 +83,8 @@ PRODUCT_PACKAGES += \ sycamore_tee_common \ sycamore_tee_imsg_log \ sycamore_tee_vfs \ - sycamore_teei_daemon \ + sycamore_teei_daemon +endif PRODUCT_VENDOR_PROPERTIES += \ ro.vendor.mtk_ufs_support=1 \ @@ -99,8 +101,10 @@ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/recovery/root/system/etc/init/zz_sycamore_hwservicemanager.rc:$(TARGET_COPY_OUT_RECOVERY)/root/system/etc/init/zz_sycamore_hwservicemanager.rc # Device-side Keystore2 database staging for Android 16 FBE. +ifneq ($(strip $(NODECRYPT)),Y) PRODUCT_COPY_FILES += \ $(DEVICE_PATH)/recovery/root/system/bin/sycamore_keystore2_stage.sh:$(TARGET_COPY_OUT_RECOVERY)/root/system/bin/sycamore_keystore2_stage.sh +endif # Stock MT8755 generic ADC thermal provider. # Recovery needs this for charger/flash/wifi/USB/board NTC thermal zones;