3

I created an image of my flash disk of my Nexus 4 as described in this question by doing

# adb pull /dev/block/mmcblk0 mmcblk0.img

The image is fully functional but I would like to push this image back to my phone and the inverse command is not working since stays there forever and no change is done.

# adb push mmcblk0.img /dev/block/mmcblk0

How can I push this image back to my phone?

3 Answers 3

5

I had this problem trying to push back a backup of my Samsung Galaxy S2, using ADB with the CWM (clockworkmod) recovery tool. When pushing to a device file, ADB simply deletes the block device file and creates a regular file in its place, and thus no data actually ends up on the mmcblk0 device.

Unfortunately, piping the output of a command into "adb shell" is not implemented either, and the "adb forward" unix sockets feature also doesn't seem to work, so it's difficult to get the backup back into the device.

The solution is to pipe the image file to netcat, and use ADB's TCP port forwarding to direct the stream into your device. However, if your CWM/busybox doesn't have network tools, you'll also need to download the arm-v7 static binary version of busybox with all the applets from http://www.busybox.net/downloads/binaries/latest/ to be able to run netcat on your device.

# wget "http://www.busybox.net/downloads/binaries/latest/busybox-armv7l"

# adb push busybox-armv7l /tmp/busybox

# adb forward tcp:6789 tcp:9876

# adb shell

~ # chmod +x /tmp/busybox

~ # /tmp/busybox nc -l -p 9876 > /dev/block/mmcblk0

Then, in a new shell:

# dd if=your-image-file.img | nc localhost 6789 &

"dd" is better than "cat" because you can check the copy's progress at intervals (replace 5647 with the PID of the DD command):

# kill -USR1 5647

48+0 records in
47+0 records out
49283072 bytes (49 MB) copied, 17.6145 s, 2.8 MB/s

Beware that writing to mmcblk0 (or the equivalent on your Android device) will obliterate even the boot and recovery partitions so is a great way to brick your device. For the record, my restore worked fine ;-)

2

I found a solution. You need to have root access to do it. The best would be to boot your Nexus using a boot insecure image.

1) I broke the image in smaller chunks in this way:

# dd bs=4096 count=983040 if=mmcblk0.img of=mmcblk0-0.img
# dd bs=4096 count=983040 skip=983040 if=mmcblk0.img of=mmcblk0-1.img
# dd bs=4096 count=983040 skip=1966080 if=mmcblk0.img of=mmcblk0-2.img
# dd bs=4096 skip=2949120 if=mmcblk0.img of=mmcblk0-3.img

2) I bzip2ed all chunks:

# bzip2 -k mmcblk0-0.img
# bzip2 -k mmcblk0-1.img
# bzip2 -k mmcblk0-2.img
# bzip2 -k mmcblk0-3.img

3) I created a ramdisk in my Nexus 4:

# adb shell mount -o size=1G -t tmpfs tmpfs /dev/ramdisk

4) I copied dd and bunzip2 into /dev/ramdisk/

5) I pushed, bunzip2ed and wrote the image chunks into the partition in pieces

# adb push mmcblk0-0.img.bz2 /dev/ramdisk
# adb shell "/dev/ramdisk/bunzip2 -c /dev/ramdisk/mmcblk0-0.img.bz2 | /dev/ramdisk/dd bs=4096 conv=notrunc of=/dev/block/mmcblk0"
# adb shell rm /dev/ramdisk/mmcblk0-0.img.bz2

# adb push mmcblk0-1.img.bz2 /dev/ramdisk
# adb shell "/dev/ramdisk/bunzip2 -c /dev/ramdisk/mmcblk0-1.img.bz2 | /dev/ramdisk/dd bs=4096 seek=983040 conv=notrunc of=/dev/block/mmcblk0"
# adb shell rm /dev/ramdisk/mmcblk0-1.img.bz2

# adb push mmcblk0-2.img.bz2 /dev/ramdisk
# adb shell "/dev/ramdisk/bunzip2 -c /dev/ramdisk/mmcblk0-2.img.bz2 | /dev/ramdisk/dd bs=4096 seek=1966080 conv=notrunc of=/dev/block/mmcblk0"
# adb shell rm /dev/ramdisk/mmcblk0-2.img.bz2

# adb push mmcblk0-3.img.bz2 /dev/ramdisk
# adb shell "/dev/ramdisk/bunzip2 -c /dev/ramdisk/mmcblk0-3.img.bz2 | /dev/ramdisk/dd bs=4096 seek=2949120 conv=notrunc of=/dev/block/mmcblk0"
# adb shell rm /dev/ramdisk/mmcblk0-3.img.bz2
2

The initial adb pull/push by-partition-id pattern in the question has merit for recovery environments. Though I didn't test for the whole of the flash ("mmcblk0"), a backup and restore by userdata partition did work in an adb activated within a lineage and "/e/" recovery.

Device is a moto-g4-play "harpia" with full disk encryption of the userdata partition and an Android 6 era partition schema (no A/B partitions). The crypto footer lives in the last bytes of the partition and the key is hardware derived, so this can only be used for backup/restore of the one device.

Activate adb in the recovery "Advanced Menu", then

adb shell ls -l /dev/block/by-name
# note down links for your partition
adb pull /dev/block/by-name/userdata userdata.img
# ... more partitions
# restore userdata again
adb push userdata.img /dev/block/mmcblk0p41

Pushing on /dev/block/by-name/ paths will run into a "No space left on device" message as soon as the tmpfs size is reached. I needed to address the proper partition-id directly.

4
  • how about 'adb pull /dev/block/dm-0' to get decrypted userdata
    – alecxs
    Jun 8, 2021 at 22:20
  • in the recovery userdata is not yet decrypted+mounted, just a busybox environ. You can then mount the /system partition and chroot or LD_LIBRARY_PATH to get to a functional(?) vdc. When I just tried I didn't get past vdc, will revisit. I understand you'd want to do this to do a migration instead of restore
    – wbob
    Jun 8, 2021 at 23:33
  • didn't know that lineageos has such limitation (never used that recovery). i am only aware of stock recovery (where adb must disabled) or twrp recovery (and clones) with encryption support
    – alecxs
    Jun 9, 2021 at 6:54
  • thanks for info about pushing by /dev/block/by-name/ (I got "No space left on device", now I will try using /dev/block/sdaX)
    – barwnikk
    Jun 13, 2021 at 10:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .