sycamore: cleanup
This commit is contained in:
parent
0e06e4cac7
commit
aa2db917a4
6 changed files with 184 additions and 320 deletions
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
204
README.md
204
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
|
||||
|
||||

|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -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/<logical>` 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.
|
||||
|
|
@ -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/`
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue