Android recovery Analysis
Functions of Recovery
Android uses the Recovery mode to restore factory settings, full-package OTA upgrades, and incremental package upgrades.
The upgrade is generally performed by running the META-INF/com/google/android/update-script in the upgrade package to execute a custom upgrade, the script is a set of recovery system can recognize the UI control, file System Operation commands, such as write_raw_image (write FLASH partition) and copy_dir (copy directory ). This package is generally downloaded to the SDCARD and CACHE partitions.
The upgrade also involves the package's digital signature. The signature method is not bad with the normal JAR file signature. The Public Key is hard compiled into recovery, which is generated at: out/target/product/XX/obj/PACKAGING/ota_keys_inc_intermediates/keys. inc.
The following describes the overall recovery process. The flowchart shows the process of loading bootloader from startup.
Bootloader starts normally. There are three methods, which are classified by command in BCB (Bootloader Control Block:
Command = "boot-recovery '→ start recovery. img. Recovery mode
Command = 'Update-radio/hboot' → update firmware (bootloader)
Others → start boot. img
Other systems and File CACHE partition files involved in rediscovery
The Recovery tool deals with the primary system through three files on the NAND cache partition. The master system (including restoring factory settings and OTA upgrades) can write the commands required for recovery and read the logs and intent during the recovery process.
/Cache/recovery/command: the recovery command, written by the main system. All commands are as follows:
-- Send_intent = anystring-write the text out to recovery. intent
-- Update_package = root: 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
/Cache/recovery/log: the recovery process log, which is read by the main system.
/Cache/recovery/intent: intent output by recovery
MISC partition content
The Bootloader Control Block (BCB) stores the recovery bootloader message. The structure is as follows:
Struct bootloader_message {
Char command [32];
Char recovery [1024];
};
Command can have the following two values:
"Boot-recovery": indicates that the recovery is in progress, or indicates that the bootloader should enter the recovery mode.
"Update-hboot/radio": indicates that bootloader updates firmware.
Recovery content
"Recovery \ n
\ N
"
The recovery command is the CACHE:/recovery/command.
Two types of Recovery CaseFACTORY RESET (Restore factory settings)
Select "Restore factory settings"
Set the system to write the "-- wipe_data" command to/cache/recovery/command
The system restarts and enters the recover mode (/sbin/recovery)
Get_args () writes "boot-recovery" and "-- wipe_data" to BCB
Erase_root () format (erase) DATA Partition
Erase_root () format (erase) CACHE Partition
Finish_recovery () erased BCB
Restart the system
Ota install (OTA update)
Upgrade the system to download the OTA package to/cache/some-filename.zip
Upgrade system write recovery command "-- update_package = CACHE: some-filename.zip"
Restart and enter recovery mode
Get_args () writes "boot-recovery" and "-- update_package =..." To BCB
Install_package () for upgrade
Finish_recovery () erased BCB
** If the installation package fails ** prompt_and_wait () is waiting for user operation, select ALT + S or ALT + W to upgrade or restore the factory settings
Main () call maybe_install_firmware_update ()
If there is firmware of hboot/radio in the package, continue; otherwise, return
Write "boot-recovery" and "-- wipe_cache" to BCB
Write firmware image to the cache Partition
Write "update-radio/hboot" and "-- wipe_cache" to BCB
Restart the system
Bootloader update firmware
Bootloader writes "boot-recovery" to BCB
Erase_root () erased the CACHE Partition
Clear BCB
Main () calls reboot () to restart the system
English document of the Recovery mode process
/Init → init. rc →/sbin/recovery →
Main (): recovery. c
Ui_init (): ui. c [UI initialize]
Gr_init (): minui/graphics. c [set tty0 to graphic mode, open fb0]
Ev_init (): minui/events. c [open/dev/input/event *]
Res_create_surface: minui/resource. c [create surfaces for all bitmaps used later, include icons, BMP]
Create 2 threads: progress/input_thread [create progress show and input event handler thread]
Get_args (): recovery. c
Get_bootloader_message (): bootloader. c [read mtdblock0 (misc partition) 2nd page for commandline]
Check if nand misc partition has boot message. If yes, fill argc/argv.
If no, get arguments from/cache/recovery/command, and fill argc/argv.
Set_bootloader_message (): bootloader. c [set bootloader message back to mtdblock0]
Parser argv [] filled abve
Register_update_commands (): commands. c [register all commands with name and hook function]
RegisterCommand (): commands. c
Register command with name, hook, type, cookie.
Commands, e. g: assert, delete, copy_dir, symlink, write_raw_image.
RegisterFunction (): commands. c
Register function with name, hook, cookie.
Function, e. g: get_mark, matches, getprop, file_contains
Install_package ():
Translate_root_path (): roots. c ["SYSTEM: lib" and turns it into a string like "/system/lib", translate the updater.zip path]
MzOpenZipArchive (): zip. c [open updater.zip file (uncompass)]
Handle_update_package (): install. c
Verify_jar_signature (): verifier. c [verify signature with keys. inc key; verify manifest and zip package archive]
VerifySignature () [verify the signature file: CERT. sf/rsa.]
DigestEntry (): verifier. c [get SHA-1 digest of CERT. sf file]
RSA_verify (public key: keys. inc, signature: CERT. rsa, CERT. sf's digest): libc/rsa. c [Verify a 2048 bit RSA PKCS1.5 signature against an expected SHA-1 hash. use public key to decrypt the CERT. rsa to get original SHA digest, then compare to digest of CERT. sf]
VerifyManifest () [Get manifest SHA1-Digest from CERT. sf. Then do digest to MANIFEST. MF. Compare them]
VerifyArchive () [verify all the files in update.zip with digest listed in MANIFEST. MF]
Find_update_script (): install. c [find META-INF/com/google/android/update-script updater script]
Handle_update_script (): install. c [read cmds from script file, and do parser, exec]
ParseAmendScript (): amend. c [call yyparse () to parse to command]
ExeCommandList (): install. c
ExeCommand (): execute. c [call command hook function]
Erase DATA/CACHE partition
Prompt_and_wait (): recovery. c [wait for user input: 1) reboot 2) update.zip 3) wipe data]
Ui_key_xxx get ALT + x keys
1) do nothing
2) install_package ('sdcard: update.zip ')
3) erase_root () → format_root_device () DATA/CACHE
May_install_firmware_update (): firmware. c [remember_firmware_update () is called by write_hboot/radio_image command, it stores the bootloader image to CACHE partition, and write update-hboot/radio command to MISC partition for bootloader message to let bootloader update itself after reboot]
Set_bootloader_message ()
Write_update_for_bootloader (): bootloader. c [write firmware image into CACHE partition with update_header, busyimage and failimage]
Finish_recovery (): recovery. c [clear the recovery command and prepare to boot a (hopefully working) system, copy our log file to cache as well (for the system to read ), and record any intent we were asked to communicate back to the system.]
Reboot ()