No description
- C 72.9%
- Makefile 17%
- Python 10.1%
SP Flash Tool aborted every flash at the userdata step. The DA accepted all
25/25 sparse chunks and then closed the session with an empty error:
CMD:END <result>ERR</result><message></message>
which the GUI reports only as FLASH-UPDATE error -1 / "Unknown error occurred,
please contact tool owner." Nothing in the log names userdata as the cause.
The image was simply too big for the partition:
built userdata.img 58288120 x 4096 = 238748139520 B (222.352 GiB)
real partition 0x37827f8000 = 238412595200 B (222.039 GiB)
userdata is the last partition, so the DA extends it to fill the storage device
and boundary-checks the image against that extended size. Note this is NOT the
0xc0000000 in MT6835_Android_scatter.xml -- that is only the nominal
pre-extension value, and sizing the image to it is wrong in the other direction
(see below).
BOARD_USERDATAIMAGE_PARTITION_SIZE was never derived from anything. Git history
shows it guessed: 112046604288 -> 238748139520, alongside the leftover comment
"123748745216 ? 238748139520 ?". It overshot the real partition by 320 MiB. The
error went unnoticed because the fastboot path (flash.sh) never flashes userdata.
Sizing has to undershoot, because the two directions are not symmetric:
too large -> hard failure, as above, with an error message that names nothing.
too small -> /data is just that much smaller, and nothing grows it. The
scatter's NEEDRESIZE is not honoured by this DA (verified: both
Download Only and Format All + Download leave the filesystem at
its built size), and /data has no 'resize' fstab flag, so fs_mgr
only ever runs fsck.f2fs on it. A 3 GiB image yields a 3 GiB
/data forever on a 222 GiB partition.
The partition also varies per eMMC part -- 222.039 GiB and >=222.311 GiB measured
on two units -- so the value must clear the smallest part in the fleet:
measured partitions 222.039 GiB (fastboot getvar, unit 1)
>=222.311 GiB (unit 2, different eMMC part)
this value 222.000 GiB = 238370684928 = 58195968 x 4096
capacity given up 40 MiB on unit 1, ~318 MiB on unit 2
A round 222 GiB keeps 40 MiB of margin under the smallest partition measured, and
the capacity given up is an accepted trade for flashing safely everywhere.
This holds only across eMMC parts of the same nominal capacity. A smaller-capacity
part would fail to flash until the constant is lowered, and at that point lowering
it is the wrong answer: add the 'resize' flag to the /data fs_mgr flags in
init/fstab.mt6835 instead, which is what the stock ALPS build on this SoC does and
which makes the image size irrelevant. That change is deliberately not made here,
because it lands in vendor.img and would drag super.img and vbmeta_vendor.img into
every bundle refresh. BoardConfig.mk records this at the point of use.
Also add tools/verify-spflash-userdata.py, so a bad size fails at package time
instead of mid-flash. It checks the image against a real unit's partition size
(--from-fastboot, or --partition-size), requires the shortfall to stay within
--max-waste-mib (default 512), confirms the f2fs superblock agrees with the sparse
header, and reports whether /data carries 'resize'. Verified against a synthetic
image at the 222 GiB target (passes, 40 MiB unused), the old 238748139520 image
(fails, names the 320 MiB overshoot), and a 3 GiB image (fails, names the
undershoot); both sparse and raw inputs exercised.
Run it against the unit with the SMALLEST eMMC part before shipping a bundle.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Change-Id: I3229166bd06b897b26ba5360d65c5edcce8b61ed
|
||
|---|---|---|
| configs | ||
| init | ||
| lib_driver_cmd_mt66xx | ||
| overlay | ||
| overlay-lineage/packages/apps/Aperture/app/src/main/res/values | ||
| sepolicy | ||
| tools | ||
| Android.bp | ||
| AndroidProducts.mk | ||
| BoardConfig.mk | ||
| device.mk | ||
| extract-files.py | ||
| lineage.dependencies | ||
| lineage_brax3.mk | ||
| manifest.xml | ||
| proprietary-files.txt | ||
| proprietary-firmware.txt | ||
| setup-makefiles.py | ||
| system.prop | ||
| vendor.prop | ||