Android
Recovery
模式
(muddogxp
原创,转载请注明
)
Recovery
简介
Android
利用Recovery
模式,进行恢复出厂设置,OTA
升级,patch
升级及firmware
升级。
升级一般通过运行升级包中的META-INF/com/google/android/update-script
脚本来执行自定义升级,脚本中是一组recovery
系统能识别的UI
控制,文件系统操作命令,例如write_raw_image
(写FLASH
分区),copy_dir
(复制目录)。该包一般被下载至SDCARD
和CACHE
分区下。如果对该包内容感兴趣,可以从http://forum.xda-developers.com/showthread.php?t=442480
下载JF
升级包来看看。
升级中还涉及到包的数字签名,签名方式和普通JAR
文件签名差不错。公钥会被硬编译入recovery
,编译时生成在:out/target/product/XX/obj/PACKAGING/ota_keys_inc_intermediates/keys.inc
G1
中的三种启动模式
MAGIC KEY:
Bootloader
正常启动,又有三种方式,按照BCB
(Bootloader
Control Block,
下节介绍)中的command
分类:
Recovery
涉及到的其他系统及文件
-
-
/cache/recovery/command
:
recovery
命令,由主系统写入。所有命令如下:
-
--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
:
recovery
过程日志,由主系统读出
-
/cache/recovery/intent
:
recovery
输出的
intent
Recovery
工具通过
NAND
cache
分区上的三个文件和主系统打交道。主系统(包括恢复出厂设置和
OTA
升级)可以写入
recovery
所需的命令,读出
recovery
过程中的
LOG
和
intent
。
-
MISC
分区内容
Bootloader Control Block
(BCB)
存放
recovery
bootloader message
。结构如下:
struct
bootloader_message {
char
command[32];
char
status[32]; //
未知用途
char
recovery[1024];
};
-
command
可以有以下两个值
“boot-recovery”
:标示
recovery
正在进行,或指示
bootloader
应该进入
recovery
mode
“update-hboot/radio”
:指示
bootloader
更新
firmware
-
recovery
内容
“recovery/n
<recovery
command>/n
<recovery
command>
”
其中
recovery
command
为
CACHE:/recovery/command
命令
两种Recovery
Case
-
用户选择“恢复出厂设置”
-
设置系统将
"--wipe_data"
命令写入
/cache/recovery/command
-
系统重启,并进入
recover
模式(
/sbin/recovery
)
-
get_args()
将
"boot-recovery"
和
"--wipe_data"
写入
BCB
-
erase_root()
格式化(擦除)
DATA
分区
-
erase_root()
格式化(擦除)
CACHE
分区
-
finish_recovery()
擦除
BCB
-
重启系统
-
升级系统下载
OTA
包到
/cache/some-filename.zip
-
升级系统写入
recovery
命令
"--update_package=CACHE:some-filename.zip"
-
重启,并进入
recovery
模式
-
get_args()
将
"boot-recovery"
和
"--update_package=..."
写入
BCB
-
install_package()
作升级
-
finish_recovery()
擦除
BCB
-
**
如果安装包失败
**
prompt_and_wait()
等待用户操作,选择
ALT+S
或
ALT+W
升级或恢复出厂设置
-
main()
调用
maybe_install_firmware_update()
-
如果包里有
hboot/radio
的
firmware
则继续,否则返回
-
将
"boot-recovery"
和
"--wipe_cache"
写入
BCB
-
将
firmware image
写入
cache
分区
-
将
"update-radio/hboot"
和
"--wipe_cache"
写入
BCB
-
重启系统
-
bootloader
自身更新
firmware
-
bootloader
将
"boot-recovery"
写入
BCB
-
erase_root()
擦除
CACHE
分区
-
清除
BCB
-
main()
调用
reboot()
重启系统
Recovery
模式流程
/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, bmps]
-
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 above
-
register_update_commands():commands.c
[ register all commands with name and hook function ]
-
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 ]
-
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 ]
-
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()
Recovery
模式流程图
以下流程图绘制了系统从启动加载
bootloader
后的行为流程。
|
|