recovery的源代码在bootable/recovery/目录。
recovery在init进程中被启动,启动过程定义在/etc/init.rc中:
在bootable/recovery/etc/init.rc中有下面的服务定义:
service recovery /sbin/recovery
seclabel u:r:recovery:s0
升级主流程在recovery.cpp中实现。
RecoveryUI类,定义了一系列虚接口,同时处理键击事件。通过一个线程读取键击事件,并插入队列。
ScreenRecoveryUI类,负责图形界面绘制和菜单管理。启动了一个线程定期跟新界面。
定义了DefaultDevice、DefaultUI。Device定义了升级操作列表。DefaultUI继承ScreenRecoveryUI。
管理分区挂载映射。分区配置文件:/etc/recovery.fstab。
读写bootloader control block,/misc分区。支持mtd,emmc存储系统。
验证安装包。
验证密钥文件位于/res/keys。
启动updater进程(下一节介绍),并与其通过管道通信,接受updater反馈的进度等信息。
#define ASSUMED_UPDATE_BINARY_NAME “META-INF/com/google/android/update-binary”
// If the package contains an update binary, extract it and run it.
static int try_update_binary(const char *path, ZipArchive zip, int wipe_cache);
接受的信息格式为:
通过adb sideload命令输入升级包升级。启动一个recovery子进程,指定“—adbd”参数。子进程将升级包存放在/tmp/update.zip。
#define ADB_SIDELOAD_FILENAME “/tmp/update.zip”
updater 就是升级包里面的 META-INF/com/google/android/update-binary 程序,在升级过程中被执行来解析执行升级脚本。
updater 在recovery的install.cpp中被调用:
在升级过程中,update-binary 被解压到/tmp/update_binary执行,命令行参数格式为:
update_binary <version> <fd> <name>
updater 进程与父进程之间通过管道通信,向父进程汇报升级状态和进度。
updater 的源代码在 bootable/recovery/updater/ 目录。
脚本文件的名称写死在update.c 中:
#define SCRIPT_NAME "META-INF/com/google/android/updater-script"
脚本里面使用时函数都定义在 install.c 中:
void RegisterInstallFunctions() {
RegisterFunction("mount", MountFn);
RegisterFunction("is_mounted", IsMountedFn);
RegisterFunction("unmount", UnmountFn);
RegisterFunction("format", FormatFn);
......
RegisterFunction("ui_print", UIPrintFn);
RegisterFunction("run_program", RunProgramFn);
}
工具applypatch和imgdiff。
工具imgdiff的源码位于:recovery/applypatch。对应的应用补丁的工具为imgpatch。imgdiff用来处理*.gz,*.zip,*.apk,*.jar,*.img
。
imgpatch以及bspatch都存在于applypatch工具中。与官方的bspatch在输入输出以及错误处理上有一些不同。根据diff文件的开头几个字节可以判断应该使用哪个补丁工具。开头为“BSDIFF40”的用bspatch处理,开头为“IMGDIFF2”用imgpatch处理。
处理分区挂载的函数库;
mtdutils.c:处理mtd分区挂载、读写,mtd分区表从/proc/mtd获取。
mounts.c:获取已经挂载节点列表,处理remount或者umount,列表从/proc/mounts获取。
MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。
小型zip解压库。
小型加密库。
小型adbd,只支持usb连接,少量命令。
小型UI库,通过opengl api绘图,并支持键盘事件输入。
一个升级脚本语言,替代amend。基于yacc语法解析器实现,内置了简单的字符串、逻辑运算符号支持,可以通过外部函数扩展功能。
源代码位于:core/java/android/os/RecoverySystem.java