Hi, couple days ago I finally can recover my EA7500v1.
Thanks for guy who developed https://pypi.org/project/qcom-nandc-pagify/ and described how SBL partitions works.
What I have done.
Need direct connection to NAND flash. On EA7500v1/EA8500 it is possible by using testpoints on PCB, which is even labeled by manufacturer.
I've superglued pinheaders onto PCB, and after that soldering wires between them and testpoints.
On this picture I've labeled which is which.
If you have programmer capable to flash 8bit parallel NAND flash, it is easy.
I've try to do it on cheap and used for this purpose raspberry pi b+ which just laying around.
I found project which is implemented bitbang nand flasher. I forked and adapted for my particular Spansion S34MS01G2 nand flash.
Connections described in source file. GPIO layout can be found there https://pinout.xyz/
BUSY GPIO3
ALE GPIO4
CLE GPIO5
RE GPIO6
CS GND
WE GPIO7
IO0:IO7 GPIO8:GPIO15
And of course ground from RPI needs to be connected to router's GND. In my case it can be accessed on UART pinheaders.
About power supply, NAND should be supplied by 1.8V, but RPI is a 3.3V.
From electrical point of view it is wrong, but in my case I didn't connect any power to router at all, I discovered that NAND seems to be powered through pull-up resistors from RPI, and 1.8 rail on router was about 1.9v, seems reasonable.
Reading and writing operation was remarkably well, and I decided to leave it without additional supply.
After wiring you can check connection by running
./rpi-raw-nand-v3 150 read_id
Program reads ID from flash and should recognize it as S34MS01G2
If all works fine you should dump existing content of flash, just in case.
./rpi-raw-nand-v3 150 read_full 0 7936 backup.bin
This dumps from mtd0 up to mtd12
You should always use read_full instead read_data, at least for qualcomm propietary partitions, as OOB contains actual data.
Recovering process is a bit messy, as you need dumps from someone who can dump mtd0-mtd12 from working router, but qualcomm nand driver in 5.4 kernel has a bug. Driver removes ECC from dump, but not all, leaves some chunks of it. I've wrote script for recovering actual data and stripping all unnecessary parts.
On the other hand nand driver in 5.10 kernel can correctly dump from mtd0 to mtd8, but corrupts mtd9 (u-boot). So in my case preferred method was get full dumps from 5.4 kernel router.
On working router you need to install nand-utils
package and run commands
nanddump -f /tmp/dumpmtd0.bin -o -n /dev/mtd0
nanddump -f /tmp/dumpmtd1.bin -o -n /dev/mtd1
nanddump -f /tmp/dumpmtd2.bin -o -n /dev/mtd2
nanddump -f /tmp/dumpmtd3.bin -o -n /dev/mtd3
... and so on
Then feed this dumps into strip_ecc.py script and you've got clean data.
After that we need to prepare raw data for flasher by adding ECC and other Qualcomm specific things.
qcom-nandc-pagify --infile mtd0_strip.bin --outfile mtd0_ecc.bin --ecc rs_sbl
qcom-nandc-pagify --infile mtd1_strip.bin --outfile mtd1_ecc.bin --ecc rs_sbl
qcom-nandc-pagify --infile mtd2_strip.bin --outfile mtd2_ecc.bin --ecc rs_sbl
... and so on
Flashing new data.
You should always try to save your mtd8 (ART) partition as it contains unique calibration data for this particular device.
As wel as mtd12 which contains serial number and other no so important stuff.
Before you can write into NAND it needs to be erased. Erasing performed by big blocks, in this case by 64 pages. Each page is a 2048 byte.
For example if you need restore SBL1, you need to erase pages from 0 to 127. Is is first two blocks.
./rpi-raw-nand-v3 150 erase_blocks 0 2
Then you can write new data onto it
./rpi-raw-nand-v3 150 write_full 0 128 mtd0_ecc.bin
Partitions table from EA7500v1
No Name Start Start page Start block Size Size pages Size blocks ECC
0 SBL1 0 0 0 0x40000 128 2 RS_SBL
1 MIBIB 0x40000 128 2 0x140000 640 10 RS_SBL
2 SBL2 0x180000 768 12 0x140000 640 10 RS_SBL
3 SBL3 0x2c0000 1408 22 0x280000 1280 20 RS_SBL
4 DDRCONFIG 0x540000 2688 42 0x120000 576 9 RS_SBL
5 SSD 0x660000 3264 51 0x120000 576 9 RS_SBL
6 TZ 0x780000 3840 60 0x280000 1280 20 RS_SBL
7 RPM 0xa00000 5120 80 0x280000 1280 20 RS_SBL
8 ART 0xc80000 6400 100 0x140000 640 10 RS
9 APPSBL 0xdc0000 7040 110 0x100000 512 8 RS_SBL
10 u_env 0xec0000 7552 118 0x40000 128 2 RS
11 s_env 0xf00000 7680 120 0x40000 128 2 RS
12 devinfo 0xf40000 7808 122 0x40000 128 2 RS
In this table I place page and blocks numbers, for writing and erasing.
Don't substitute page numbers in erase_blocks command!
In ECC column shown which format was used in partition. Description and differences between them, you can find in qcom-nandc-pagify docs.
For successfully boot in U-Boot you need all chain from SBL1 up to RPM plus APPSBL.
Recovering process can be observed by hooking logic analyzer/oscilloscope up to one of the nand's data pin.
This is a chart I've captured on my router and marked what partitions loading. If boot process fails after some stage, you can figure which is caused.
In my repo https://github.com/iglooom/rpi-tsop48-nand/tree/master/qca-sbl-dumps/raw-nand-dumps you can find raw NAND dumps which I've dumped from working router after recovery. You can simply flash it by external flasher.
I can't check is this dumps can work on 8500, but as I upgraded RAM on my 7500 I've flash mtd4 exactly from 8500 dump and it recognized 512M. So, it seems to be should work on real 8500 too.
And after all of that I've performed some tests, and it seems to be impossible to correctly flash this partitions from OpenWRT, it always corrupted by driver in some way.
Read-only flag on those not a coincidence, don't try this at home