I'm currently maintaining the Conductor App for PhoneLab testbed. One of the core tasks performed by conductor is to perform system OTA update, so that we can push platform changes to our participants, either to fix bugs, or to do system level experiments (libc, Dalvik VM, etc.).
So the first step is, how to create an OTA package?
Suppose we have a patched version of
libc and we want to overwrite the
previous one already in participants' phone, we need first to figure out where
that file is in the file system. In this case, it's
our OTA package's directory structure must looks like this:
myupdate |-- META-INF | `-- com | `-- google | `-- android | |-- update-binary | `-- updater-script `-- system `-- lib `-- libc.so
updater-script are used to actually perform the
update, I'll explain them later.
Note that the structure of the
system needs to be exactly the same with what's
in Android's setup, so that we can copy that directory directly to target
system, and overwrite the files with the updated version.
update-binary, as its name indicates, is a binary file that will parse the
updater-script we write. It's quite standard and nothing special. You can obtain
a copy of this file here.
In this case, what we need to do is quite simple: mount the
and copy the files in the OTA package to target file system. So the
updater-script may looks like this:
mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system"); package_extract_dir("system", "/system"); unmount("/system");
First, we mount the target file system's
system partition using the
command, the arguments are:
FSTYPE: File system type. In this case, it's "ext4"
TYPE: Storage type. "EMMC" means internal solid state storage device on MMC bus, which is actually NAND flash.
DEV: The device to mount.
PATH: Mount point.
You can find all the mounted devices in Android by
adb shell then
Here is one sample output:
shell@android:/ $ mount rootfs / rootfs ro,relatime 0 0 tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0 devpts /dev/pts devpts rw,relatime,mode=600 0 0 proc /proc proc rw,relatime 0 0 sysfs /sys sysfs rw,relatime 0 0 none /acct cgroup rw,relatime,cpuacct 0 0 tmpfs /mnt/secure tmpfs rw,relatime,mode=700 0 0 tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0 tmpfs /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0 none /dev/cpuctl cgroup rw,relatime,cpu 0 0 /dev/block/platform/omap/omap_hsmmc.0/by-name/system /system ext4 ro,relatime,barrier=1,data=ordered 0 0 /dev/block/platform/omap/omap_hsmmc.0/by-name/efs /factory ext4 ro,relatime,barrier=1,data=ordered 0 0 /dev/block/platform/omap/omap_hsmmc.0/by-name/cache /cache ext4 rw,nosuid,nodev,noatime,errors=panic,barrier=1,nomblk_io_submit,data=ordered 0 0 /dev/block/platform/omap/omap_hsmmc.0/by-name/userdata /data ext4 rw,nosuid,nodev,noatime,errors=panic,barrier=1,nomblk_io_submit,data=ordered 0 0 /sys/kernel/debug /sys/kernel/debug debugfs rw,relatime 0 0 /dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
Then we do the actual copy using
package_extract_dir command. This will copy
And finally we unmount the
Pack It Up
myupdate directory, use this command to create the zip file.
zip -r9 ../myupdate.zip *
Note that the command is executed inside the
myupdate directory, and the
zip file is created in parent directory. This is because the
system directory must be in the root directory of the final zip file.
Sign the OTA Package
Up to this point, the OTA package we just created should be able to applied successfully on custom recoveries like CWM, in which the signature verification is turned off by default.
However, to automate the OTA process, we're using the Android RecoverySystem to reboot the phone and apply the update, in that case, the signature verification is turned on. So we need to sign the package with proper keys, which are platform keys.
Suppose you've get the platform keys named
platform.pk8, we can use the signapk.jar tool.
java -jar signapk.jar -w platform.x509.pem platform.pk8 myupdate.zip myupdate-signed.zip
- We need the
-wflag to sign the whole zip file.
- The sequence of the two key files: pem file goes first, then the pk8 file.
This will generate the final OTA package,
myupdate-signed.zip, which WILL pass
the signature verification of the recovery system.