Fork me on GitHub

Android OTA Update


Android OTA Update

# first, build the target-files .zip
% . build/envsetup.sh && lunch tardis-eng
% mkdir dist_output
% make dist DIST_DIR=dist_output
  [...]
% ls -l dist_output/*target_files*
-rw-r----- 1 user eng  69965275 Sep 29 15:51 tardis-target_files.zip
# The target-files .zip contains everything needed to construct OTA packages.
% ./build/tools/releasetools/ota_from_target_files \
    dist_output/tardis-target_files.zip ota_update.zip
unzipping target target-files...
done.
% ls -l ota_update.zip
-rw-r----- 1 user eng 62236561 Sep 29 15:58 ota_update.zip
% ./build/tools/releasetools/ota_from_target_files \
    -i PREVIOUS-tardis-target_files.zip \  # make incremental from this older version
    dist_output/tardis-target_files.zip incremental_ota_update.zip
unzipping target target-files...
unzipping source target-files...
   [...]
done.
% ls -l incremental_ota_update.zip
-rw-r----- 1 user eng 1175314 Sep 29 16:10 incremental_ota_update.zip
#To generate a block-based OTA for subsequent updates, pass the --block option to ota_from_target_files.

adb fastboot places the exact same bits on the device as a full OTA, so flashing is compatible with block OTA.

If a file is corrupted, a file OTA succeeds as long as it doesn't touch the corrupted file, but a block OTA fails if it detects any corruption on the system partition.

The system builds the updater binary from bootable/recovery/updater and uses it in an OTA package.The package itself is a .zip file (ota_update.zip, incremental_ota_update.zip) that contains the executable binary META-INF/com/google/android/update-binary.Updater contains several builtin functions and an interpreter for an extensible scripting language (edify) that supports commands for typical update-related tasks. Updater looks in the package .zip file for a script in the file META-INF/com/google/android/updater-script.Using the edify script and/or builtin functions is not a common activity, but can be helpful if you need to debug the update file.

An edify script is a single expression in which all values are strings. Empty strings are false in a Boolean context and all other strings are true. Edify supports the following operators (with the usual meanings):

(expr )
 expr + expr  # string concatenation, not integer addition
 expr == expr
 expr != expr
 expr && expr
 expr || expr
 ! expr
 if expr then expr endif
 if expr then expr else expr endif
 function_name(expr, expr,...)
 expr; expr

A sample partition map file might look like this:

device/yoyodyne/tardis/recovery.fstab
# mount point       fstype  device       [device2]        [options (3.0+ only)]

/sdcard     vfat    /dev/block/mmcblk0p1 /dev/block/mmcblk0
/cache      yaffs2  cache
/misc       mtd misc
/boot       mtd boot
/recovery   emmc    /dev/block/platform/s3c-sdhci.0/by-name/recovery
/system     ext4    /dev/block/platform/s3c-sdhci.0/by-name/system length=-4096
/data       ext4    /dev/block/platform/s3c-sdhci.0/by-name/userdata

There are five supported filesystem types:yaffs2,mtd,ext4,emmc,vfat.

Starting in Android 3.0, the recovery.fstab file gains an additional optional field, options. Currently the only defined option is length , which lets you explicitly specify the length of the partition. This length is used when reformatting the partition (e.g., for the userdata partition during a data wipe/factory reset operation, or for the system partition during installation of a full OTA package). If the length value is negative, then the size to format is taken by adding the length value to the true partition size. For instance, setting "length=-16384" means the last 16k of that partition will not be overwritten when that partition is reformatted. This supports features such as encryption of the userdata partition (where encryption metadata is stored at the end of the partition that should not be overwritten).

#$subject should be changed to reflect your organization's information.
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media; do \
    ./development/tools/make_key ~/.android-certs/$x "$subject"; \
done
make dist
./build/tools/releasetools/sign_target_files_apks \
    -o \    # explained in the next section
    -d ~/.android-certs out/dist/*-target_files-*.zip \
    signed-target_files.zip

The sign_target_files_apks script takes a target-files .zip as input and produces a new target-files .zip in which all the .apks have been signed with new keys. The newly signed images can be found under IMAGES/ in signed-target_files.zip.

./build/tools/releasetools/ota_from_target_files \
    -k ~/.android-certs/releasekey \
    signed-target_files.zip \
    signed-ota_update.zip
#device/yoyodyne/apps/SpecialApp/Android.mk
 [...]

LOCAL_CERTIFICATE := device/yoyodyne/security/special
#Now the build uses the device/yoyodyne/security/special.{x509.pem,pk8} key to sign SpecialApp.apk. The build can use only private keys that are not password protected.
# generate RSA key
% openssl genrsa -3 -out temp.pem 2048
Generating RSA private key, 2048 bit long modulus
....+++
.....................+++
e is 3 (0x3)

# create a certificate with the public part of the key
% openssl req -new -x509 -key temp.pem -out releasekey.x509.pem \
  -days 10000 \
  -subj '/C=US/ST=California/L=San Narciso/O=Yoyodyne, Inc./OU=Yoyodyne Mobility/CN=Yoyodyne/emailAddress=yoyodyne@example.com'

# create a PKCS#8-formatted version of the private key
% openssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt

# securely delete the temp.pem file
% shred --remove temp.pem

The openssl pkcs8 command given above creates a .pk8 file with no password, suitable for use with the build system. To create a .pk8 secured with a password (which you should do for all actual release keys), replace the -nocrypt argument with -passout stdin; then openssl will encrypt the private key with a password read from standard input.

./build/tools/releasetools/img_from_target_files signed-target-files.zip signed-img.zip

The resulting file, signed-img.zip, contains all the .img files. To load an image onto a device, use fastboot as follows:fastboot update signed-img.zip.