i had a problem with a customer phone and flashing roms, radios and all that stuff doesn't help at all.
so i decided to do a nandroid restore in my own way.
first of all here you are what you need:
- good knowledge of linux common commands/tools
- the damaged phone ( with recovery accessible )
- a good phone of the same model [ optional ]
you don't need a good phone if you already make a dd backup of the damaged one when it was running fine ( explained later ).
NOTE: if you got some connection error while launching netcat ( nc ) try to run the adb forward command again from another shell.
step 1
read from good
first of all we need to read the whole emmc from the good phone ( i suggest to do this in recovery, when your phone doesn't use emmc so much ):
adb forward tcp:4444 tcp:4444now, from another shell:
adb shell
su
nc -l -p 4444 -e dd if=/dev/block/mmcblk0
adb forward tcp:4444 tcp:4444...wait...
nc 127.0.0.1 4444 > backup.dd
congratulations! now you have a bulletproof backup of a phone.
setp 2
understand where is the recovery
since you are going to overwrite the whole emmc you must be sure to not overwrite something that is in use while you are doing the restore job.so, you need a lot of oil for your brain gears.
2 hints that will save you hours of googling: /proc/emmc or /proc/mtd have the names of your partitions, and /proc/partitions have their sizes.
so, after you figured out which partition is the recovery one, lets find out where it starts in our backup.
use fdisk -l on the bakup image ( backup.dd ) to find out where our recovery starts.
here is my output:
Warning: omitting partitions after #60.
They will be deleted if you save this partition table.
Disk mmcblk0: 15.6 GB, 15634268160 bytes, 30535680 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
mmcblk0p1 * 1 256 128 4d QNX4.x
mmcblk0p2 257 768 256 51 OnTrack DM6 Aux1
mmcblk0p3 769 262110 130671 5d Unknown
mmcblk0p4 262111 30535678 15136784 5 Extended
mmcblk0p5 262112 262143 16 5a Unknown
mmcblk0p6 262145 262656 256 73 Unknown
mmcblk0p7 262658 293812 15577+ 5b Unknown
mmcblk0p8 293814 294325 256 5c Priam Edisk
mmcblk0p9 294327 296374 1024 45 Unknown
mmcblk0p10 296376 296887 256 47 Unknown
mmcblk0p11 296889 300984 2048 46 Unknown
mmcblk0p12 300986 303033 1024 4c Unknown
mmcblk0p13 303035 303098 32 0 Empty
mmcblk0p14 303100 315387 6144 34 Unknown
mmcblk0p15 315389 317436 1024 36 Unknown
mmcblk0p16 317438 319485 1024 0 Empty
mmcblk0p17 319487 411646 46080 77 Unknown
mmcblk0p18 411648 432127 10240 7a Unknown
mmcblk0p19 432129 442368 5120 0 Empty
mmcblk0p20 442370 458750 8190+ 74 Unknown
mmcblk0p21 458752 491519 16384 48 Unknown
mmcblk0p22 491521 524287 16383+ 71 Unknown
mmcblk0p23 524289 526333 1022+ 76 Unknown
mmcblk0p24 526335 534526 4096 4a Unknown
mmcblk0p25 534528 542719 4096 4b Unknown
mmcblk0p26 542721 583680 20480 19 Unknown
mmcblk0p27 583682 583689 4 0 Empty
mmcblk0p28 583691 584202 256 23 Unknown
mmcblk0p29 584204 584235 16 0 Empty
mmcblk0p30 584237 586797 1280+ 0 Empty
mmcblk0p31 586799 586926 64 0 Empty
mmcblk0p32 586928 786431 99752 0 Empty
mmcblk0p33 786433 4194302 1703935 83 Linux
mmcblk0p34 4194304 4718590 262143+ 83 Linux
mmcblk0p35 4718592 30408703 12845056 83 Linux
mmcblk0p36 30408705 30508704 50000 c W95 FAT32 (LBA)
mmcblk0p37 262112 262143 16 5a Unknown
mmcblk0p38 262145 262656 256 73 Unknown
mmcblk0p39 262658 293812 15577+ 5b Unknown
[garbage truncated...]
NOTE: there is a lot of garbage, if you known that there is 36 partitions, just ignore everything comes after.
for me the recovery partition is the 22.
my partition start at block #491521 ( NOTE that i wrote block, not byte ).
you HAVE TO run some test before start writing, to be sure that your offset/sizes are correct.
[from adb]
dd if=/dev/block/mmcblk0 count=1 of=/dev/null
this will return how many bytes are stored in one block of your emmc, the BLOCK_SIZE.
now the output from your workstation:
dd if=backup.dd bs=1 skip=$(( START_BLOCK * BLOCK_SIZE )) count=100 | hexdump -Cshould be the same of this command from adb:
dd if=RECOVERY_PARTITION bs=1 count=100 | hexdump -C
replace:
START_BLOCK with the block # where your partition starts ( 491521 for me )
BLOCK_SIZE with the size of one bolck of your emmc
RECOVERY_PARTITION with the partition to where the recovery it's stored ( /dev/block/mmcblk0p22 for me )
is it all ok? is everything correct? are you sure?
well, just for be very sure of what we are going to do let's test the next important address.
let's check that the recovery partition ends where we think that it will.
from the fdisk output let's take the start block of the partition next to the recovery one.
for me it's partition 23 ( 22 + 1 ), which start on #524289, it will be our END_BLOCK.
now repeat the previous commands changing partition number and start_block.
you should have the same output from adb and your workstation.
step 3
writing to damaged phone
we are now ready to write the whole good emmc to the damaged phone, skipping the recovery partition.
let's do this.
reboot the damaged phone into recovery.
start copying everything before the recovery.
adb forward tcp:4444 tcp:4444
adb shell
su
nc -l -p 4444 -e dd bs=1 of=/dev/block/mmcblk0
from another shell:
adb forward tcp:4444 tcp:4444
dd if=backup.dd bs=1 count=$(( START_BLOCK * BLOCK_SIZE )) | nc 127.0.0.1 4444
...wait...
let's copy everything after the recovery partition:
[from adb]
nc -l -p 4444 -e dd bs=1 seek=$((END_BLOCK * BLOCK_SIZE )) of=/dev/block/mmcblk0
from your workstation:
dd if=backup.dd bs=1 skip=$(( END_BLOCK * BLOCK_SIZE )) | nc 127.0.0.1 4444
PS: ignore dd warnings about lseek64 if any.
that's all folks!
if your device still KO please ensure to change device specific data.
for example HTC writes the phone IMEI into /dev/bock/mmcblk0p4 ( facepalm )
please ask for device-specific partitions in the device forum on XDA.
for any question feel free to comment this post, i'll answer ASAP.
-- tux_mind