This article discusses how to create update.zip file and how Android Over-The-Air updates use such file to update the operating system on the device.
Creating update.zip
Tip
| The following instructions are extrapolated by reading the source code in /bootable/recovery/ folder of the source tree, especially recovery.c and roots.c. |
Create directories
First, we want to create a placeholder and structure for our update file.
mkdir -p myupdate/META-INF/com/google/android cd myupdate
Create update-script
Next, create a file with name update-script in META-INF/com/google/android folder.
show_progress 0.1 0 copy_dir PACKAGE:system SYSTEM: show_progress 1.0 10
The following is the list of commands that is recognized in
copy_dir
-
Syntax
-
copy_dir <src-dir> <dst-dir> [<timestamp>]
Description
-
Copy the contents of <src-dir> to <dst-dir>. The original contents of <dst-dir> are preserved unless something in <src-dir> overwrote them.
Example
-
copy_dir PACKAGE:system SYSTEM:
format
-
Syntax
-
format <root>
Description
-
Format a partitionExample: format SYSTEM:, will format entire /system . Note: formatting erases data irreversibly.
delete
-
Syntax
-
delete <file1> [... <fileN>]
Description
-
Delete file.
Example
-
delete SYSTEM:app/Calculator.apk, will delete Calculator.apk from system/app directory.
delete_recursive
-
Syntax
-
delete_recursive <file-or-dir1> [... <file-or-dirN>]
Description
-
Delete a file or directory with all of it’s contents recursively
Example
-
delete_recursive DATA:dalvik-cache, will delete /data/dalvik-cache directory with all of it’s contents
run_program
-
Syntax
-
run_program <program-file> [<args> ...]
Description
-
Run an external program included in the update package.
Example
-
run_program PACKAGE:install_busybox.sh, will run install_busybox.sh script (shell command) included in the update package.
set_perm
-
Syntax
-
set_perm <uid> <gid> <mode> <path> [... <pathN>]
Description
-
Set ownership and permission of single file or entire directory trees, like `chmod’, `chown’, and `chgrp’ all in one
Example
-
set_perm 0 2000 0550 SYSTEM:etc/init.goldfish.sh
set_perm_recursive
-
Syntax
-
set_perm_recursive <uid> <gid> <dir-mode> <file-moe> <path> [... <pathN>]
Description
-
Set ownership and permission of a directory with all of it’s contents recursively
Example
-
set_perm_recursive 0 0 0755 0644 SYSTEM:app
show_progress
-
Syntax
-
show_progress <fraction> <duration>
Description
-
Use of the on-screen progress meter for the next operation, automatically advancing the meter over <duration> seconds (or more rapidly if the actual rate of progress can be determined).
Example
-
show_progress 0.1 0
symlink
-
Syntax
-
ymlink <link-target> <link-path>
Description
-
Create a symlink (like `ln-s’). The <link-path> is in root:path format, but <link-target> isfor the target filesystem (and may be relative)
Partitions
Partition | Linux block device | /mountpoint/ | fs | size | Description. |
---|---|---|---|---|---|
BOOT | (/dev/mtdblock[?]) | / | (RAM) | Raw | Kernel, ramdisk and boot config. |
DATA | (/dev/mtdblock5) | /data/ | yaffs2 | 91904kb | User, system config, app config, and apps (without a2sd) |
CACHE | (/dev/mtdblock4) | /cache/ | yaffs2 | 30720kb | OTA cache, Recovery/update config and temp |
MISC | (/dev/mtdblock[?]) | N/A | Raw | N/A | TODO Not sure what it does. |
PACKAGE | (Relative to package file) | N/A | N/A | N/A | Pseudo-filesystem for update package. |
RECOVERY | (/dev/mtdblock[?]) | / | Raw | [?]kb | The recovery and update environment’s kernel and ramdisk. Similar to BOOT. |
SDCARD | (/dev/mmcblk0(p1)) | /sdcard/ | fat32 | 32MB-32GB | The microSD card. Update zip is usually here. |
SYSTEM | (/dev/mtdblock3) | /system/ | yaffs2 | 92160kb | The OS partition, static and read-only. |
Create signed ZIP file
Generate a new key:
openssl genrsa -out key.pem 1024 openssl req -new -key key.pem -out request.pem openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocrypt
Sign your update.zip
zip myupdate.zip myupdate/ java -jar SignApk/signapk.jar certificate.pem key.pk8 myupdate.zip update.zip
Note
| We assume you have signapk.jar downloaded. Instructions on where to get it are here: Generating Keys |
Over The Air updates (OTA)
The recovery tool communicates with the main system through /cache files:
-
/cache/recovery/command - INPUT - command line for tool, one arg per line
-
/cache/recovery/log - OUTPUT - combined log file from recovery run(s)
-
/cache/recovery/intent - OUTPUT - intent that was passed in
The arguments which may be supplied in the recovery.command file:
-
--send_intent=anystring - write the text out to recovery.intent
-
--update_package=path - verify install an OTA package file
-
--wipe_data - erase user data (and cache), then reboot
-
--wipe_cache - wipe cache (but not user data), then reboot
-
--set_encrypted_filesystem=on|off - enables / diasables encrypted fs
After completing, we remove /cache/recovery/command and reboot.Arguments may also be supplied in the bootloader control block (BCB).These important scenarios must be safely restartable at any point:
Factory Reset
-
user selects factory reset
-
main system writes --wipe_data to /cache/recovery/command
-
main system reboots into recovery
-
get_args() writes BCB with boot-recovery and --wipe_data — after this, rebooting will restart the erase --
-
erase_volume() reformats /data
-
erase_volume() reformats /cache
-
finish_recovery() erases BCB — after this, rebooting will restart the main system --
-
main() calls reboot() to boot main system
OTA Install
-
main system downloads OTA package to /cache/some-filename.zip
-
main system writes --update_package=/cache/some-filename.zip
-
main system reboots into recovery
-
get_args() writes BCB with boot-recovery and --update_package=... — after this, rebooting will attempt to reinstall the update --
-
install_package() attempts to install the update NOTE: the package install must itself be restartable from any point
-
finish_recovery() erases BCB — after this, rebooting will (try to) restart the main system --
-
if install failed
-
prompt_and_wait() shows an error icon and waits for the user
-
the user reboots (pulling the battery, etc) into the main system
-
-
main() calls maybe_install_firmware_update()
-
if the update contained radio/hboot firmware
-
m_i_f_u() writes BCB with boot-recovery and --wipe_cache — after this, rebooting will reformat cache & restart main system --
-
m_i_f_u() writes firmware image into raw cache partition
-
m_i_f_u() writes BCB with update-radio/hboot and --wipe_cache — after this, rebooting will attempt to reinstall firmware --
-
bootloader tries to flash firmware
-
bootloader writes BCB with boot-recovery (keeping --wipe_cache) — after this, rebooting will reformat cache & restart main system --
-
erase_volume() reformats /cache
-
finish_recovery() erases BCB — after this, rebooting will (try to) restart the main system --
-
main() calls reboot() to boot main system
-
Secure File System Enabled/Disabled
-
user selects enable encrypted file systems
-
main system writes --set_encrypted_filesystems=on|off to /cache/recovery/command
-
main system reboots into recovery
-
get_args() writes BCB with boot-recovery and --set_encrypted_filesystems=on|off — after this, rebooting will restart the transition --
-
read_encrypted_fs_info() retrieves encrypted file systems settings from /data Settings include: property to specify the Encrypted FS istatus and FS encryption key if enabled (not yet implemented)
-
erase_volume() reformats /data
-
erase_volume() reformats /cache
-
restore_encrypted_fs_info() writes required encrypted file systems settings to /data Settings include: property to specify the Encrypted FS status and FS encryption key if enabled (not yet implemented)
-
finish_recovery() erases BCB — after this, rebooting will restart the main system --
-
main() calls reboot() to boot main system