This post lists some notes on restoring a Nexus device to Android factory image using a Linux machine as the development host. I tested this guide with a Nexus 4 running Cyanogenmod 12.1-20150704. Use these notes together with my guide How to set up a debugging and development environment for Android on Linux and Google’s Factory Images for Nexus Devices.

Note: I’m omitting values particular to my system (like ids, serial numbers and ports) with the notation <variable>.

Warning: Following this procedure will result in loss of user and system data. Always backup your data.

Contents:

Prepare system image and device

Download latest factory image for your device, in this case for a Nexus 4 Occam

$ curl -O https://dl.google.com/dl/android/aosp/occam-lmy47v-factory-b0c4eb3d.tgz

Always remember to verify the integrity of the downloaded files by comparing the checksums to the ones published by Google.

$ md5sum occam-lmy47v-factory-b0c4eb3d.tgz
be10a86e3b70ec271670f008cc51aa58  occam-lmy47v-factory-b0c4eb3d.tgz
$ sha1sum occam-lmy47v-factory-b0c4eb3d.tgz
b0c4eb3d2289bbb7dbc47ec77ca4be6b657cd9fc  occam-lmy47v-factory-b0c4eb3d.tgz

Untar compressed file

$ tar xzf occam-lmy47v-factory-b0c4eb3d.tgz

If you haven’t set up your development and debugging environment, follow the steps in sections Install the Android SDK Tools, Configure the Nexus device for development and Unlock the bootloader of my guide mentioned before.

Plug your device with the USB cable and detect it with adb

$ adb devices -l
* daemon not running. starting it now on port <portnumber> *
* daemon started successfully *
List of devices attached
<XXXXXXXXXXXXXXXX>       device usb:1-1 product:occam model:Nexus_4 device:mako

Boot into bootloader

$ adb reboot bootloader

Once in fastboot mode, verify fastboot correctly sees the device.

$ fastboot devices -l
<ok message, not errors>

This step will wipe all device data. Unlock bootloader with below command. Accept the disclaimer displayed, then you will see the output shown below.

$ fastboot oem unlock # Accept disclaimer
...
OKAY [ 13.613s]
finished. total time: 13.613s

If the device doesn’t reboot by itself, reboot it from the menu.

Flash the image

Change current directory into the one containing the script flash-all.sh and just execute it

$ cd occam-lmy47v
$ ./flash-all.sh
[113/574]
sending 'bootloader' (2264 KB)...
OKAY [  0.076s]
writing 'bootloader'...
OKAY [  0.205s]
finished. total time: 0.282s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.051s
sending 'radio' (45537 KB)...
OKAY [  1.502s]
writing 'radio'...
OKAY [  1.885s]
finished. total time: 3.388s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.051s
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
archive does not contain 'vendor.img'
Creating filesystem with parameters:
Size: 14129561600
Block size: 4096
Blocks per group: 32768
Inodes per group: 8144
Inode size: 256
Journal blocks: 32768
Label:
Blocks: 3449600
Block groups: 106
Reserved block group size: 847
Created filesystem with 11/863264
inodes and 95427/3449600 blocks
Created filesystem with 11/863264 inodes and 95427/3449600 blocks
[81/574]
Creating filesystem with parameters:
Size: 587202560
Block size: 4096
Blocks per group: 32768
Inodes per group: 7168
Inode size: 256
Journal blocks: 2240
Label:
Blocks: 143360
Block groups: 5
Reserved block group size: 39
Created filesystem with 11/35840 inodes
and 4616/143360 blocks
--------------------------------------------
Bootloader Version...: MAKOZ30f
Baseband Version.....:
M9615A-CEFWMAZM-2.0.1701.07
Serial Number........: 02163655dc08e411
--------------------------------------------
checking product...
OKAY [  0.002s]
checking version-bootloader...
OKAY [  0.002s]
checking version-baseband...
OKAY [  0.002s]
sending 'boot' (6398 KB)...
OKAY [  0.205s]
writing 'boot'...
OKAY [  0.280s]
sending 'recovery' (6960 KB)...
OKAY [  0.226s]
writing 'recovery'...
OKAY [  0.288s]
erasing 'system'...
OKAY [  0.829s]
sending 'system' (834754 KB)...
OKAY [ 27.140s]
writing 'system'...
OKAY [ 36.382s]
erasing 'userdata'...
OKAY [  1.502s]
sending 'userdata' (137438 KB)...
OKAY [  4.361s]
writing 'userdata'...
OKAY [  5.842s]
erasing 'cache'...
OKAY [  0.049s]
sending 'cache' (10984 KB)...
OKAY [  0.349s]
writing 'cache'...
OKAY [  0.487s]
rebooting...

finished. total time: 78.004s

Your Nexus will boot the factory image, remember that the first boot usually takes more time than usual. If you seem to get the boot loop (boot animation never stops for more than 30 minutes), power off device, start in recovery mode and wipe the user and cache data partitions. Then reboot.

This step is optional but recommended. Re-lock the bootloader by booting into fastboot mode again and running below command.

$ fastboot oem lock

Flashing the image on a memory constrained host

The script flash-all.sh tries to flash the images without sparsing them, which won’t work if you don’t have enough RAM on your development computer. For example, trying to flash the images on my 1 GiB RAM netbook running Ubuntu failed as shown

$ # Showing available RAM
$ cat /proc/meminfo | head -1
MemTotal:        1019096 kB

$ ./flash-all.sh
sending 'bootloader' (2264 KB)...
OKAY [  0.108s]
writing 'bootloader'...
OKAY [  0.203s]
finished. total time: 0.312s
rebooting into bootloader...
OKAY [  0.000s]
finished. total time: 0.051s
sending 'radio' (45537 KB)...
OKAY [  2.145s]
writing 'radio'...
OKAY [  1.887s]
finished. total time: 4.032s
rebooting into bootloader...
OKAY [  0.000s]
finished. total time: 0.051s
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
failed to allocate 854788148 bytes
error: update package missing system.img

In this case you’ll have to separately flash the images to the Nexus. Start by unzipping the ZIP file

$ unzip image-occam-lmy47v.zip
Archive:  image-occam-lmy47v.zip
inflating: android-info.txt
inflating: cache.img
inflating: boot.img
inflating: recovery.img
inflating: userdata.img
inflating: system.img

Execute the script flash-base.sh. The device will reboot into fastboot mode twice.

$ ./flash-base.sh
sending 'bootloader' (2264 KB)...
OKAY [  0.108s]
writing 'bootloader'...
OKAY [  0.202s]
finished. total time: 0.310s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.077s
sending 'radio' (45537 KB)...
OKAY [  2.146s]
writing 'radio'...
OKAY [  1.882s]
finished. total time: 4.028s
rebooting into bootloader...
OKAY [  0.000s]
finished. total time: 0.051s

Flash the recovery and boot images

$ fastboot flash recovery recovery.img
sending 'recovery' (6960 KB)...
OKAY [  0.330s]
writing 'recovery'...
OKAY [  0.299s]
finished. total time: 0.630s

$ fastboot flash boot boot.img
sending 'boot' (6398 KB)...
OKAY [  0.312s]
writing 'boot'...
OKAY [  0.262s]
finished. total time: 0.575s

Flash the system image.

$ fastboot flash -S 512M system system.img
erasing 'system'...
OKAY [  0.471s]
sending sparse 'system' (518095 KB)...
OKAY [ 58.201s]
writing 'system'...
OKAY [ 20.726s]
sending sparse 'system' (316658 KB)...
OKAY [ 35.813s]
writing 'system'...
OKAY [ 12.635s]
finished. total time: 127.845s

Note that the command uses the option -S 512M, making fastboot flash the image in chunks of (maximum) size 512 MB. Use another argument according to your system’s needs. In principle you can use this option to sparse the other images too, although you probably won’t need to do that since they aren’t as big as the system image. Fastboot describes this option’s usage as follows

  -S <size>[K|M|G]                         automatically sparse files greater
                                         than size.  0 to disable

Flash the cache and user data images.

$ fastboot flash cache cache.img
erasing 'cache'...
OKAY [  0.026s]
sending 'cache' (13424 KB)...
OKAY [  0.666s]
writing 'cache'...
OKAY [  0.530s]
finished. total time: 1.222s

$ fastboot flash userdata userdata.img
erasing 'userdata'...
OKAY [  0.474s]
sending 'userdata' (98413 KB)...
OKAY [  4.849s]
writing 'userdata'...
OKAY [  3.662s]
finished. total time: 8.986s

This step is optional but recommended. Re-lock the bootloader.

$ fastboot oem lock

Finally reboot the device

$ fastboot reboot

References