2019独角兽企业重金招聘Python工程师标准>>>

  • Recovery Binary: (http://wenbind.blogcn.com/)

  Recovery Binary 是 Android 进入 Recovery 模式所运行的程序,实现了 Recovery 模式下的功能。它由目录 bootable/recovery 下的源代码编译生成。头文件 bootable/recovery/recovery_ui.h 定义了 Recovery UI 的接口,bootable/recovery/default_recovery_ui.c 是其默认实现,每个设备可以有自己不同的实现,然后通过变量 TARGET_RECOVERY_UI_LIB 来指定,否则使用默认实现。

# bootable/recovery/Android.mk

ifeq ($(TARGET_RECOVERY_UI_LIB),)
LOCAL_SRC_FILES + = default_recovery_ui.c
else
LOCAL_STATIC_LIBRARIES + =  $(TARGET_RECOVERY_UI_LIB)
endif

  • Recovery Image:

  Recovery Image 的生成规则在文件 build/core/Makefile 中定义,具体分析如下:

# build/core/Makefile

# -----------------------------------------------------------------
# Recovery image

# If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true
ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY) $(BUILD_TINY_ANDROID)))

INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img

recovery_initrc := $(call include-path-for, recovery)/etc/init.rc
recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system
recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img
recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET)
recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery)/recovery
recovery_resources_common := $(call include-path-for, recovery)/res
recovery_resources_private := $(strip $(wildcard$(TARGET_DEVICE_DIR)/recovery/res))
recovery_resource_deps := $(shell find $(recovery_resources_common) \
$(recovery_resources_private) -type f)
recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab))
recovery_mmc_fstab := $(strip $(wildcard$(TARGET_DEVICE_DIR)/recovery_mmc.fstab))

ifeq ($(recovery_resources_private),)
$(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE))
endif

ifeq ($(recovery_fstab),)
$(info No recovery.fstab for TARGET_DEVICE $(TARGET_DEVICE))
endif

INTERNAL_RECOVERYIMAGE_ARGS := \
$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
--kernel $(recovery_kernel) \
--ramdisk $(recovery_ramdisk)

# Assumes this has already been stripped
ifdef BOARD_KERNEL_CMDLINE
INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
endif
ifdef BOARD_KERNEL_BASE
INTERNAL_RECOVERYIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
endif
BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
ifdef BOARD_KERNEL_PAGESIZE
INTERNAL_RECOVERYIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
endif

INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
kernel: $(INSTALLED_BOOTIMAGE_TARGET)
.PHONY: kernel

# Keys authorized to sign OTA packages this build will accept. The
# build always uses test-keys for this; release packaging tools will
# substitute other keys for this one.
OTA_PUBLIC_KEYS := $(SRC_TARGET_DIR)/product/security/testkey.x509.pem

# Generate a file containing the keys that will be read by the
# recovery binary.
RECOVERY_INSTALL_OTA_KEYS := \
$(call intermediates-dir-for,PACKAGING,ota_keys)/keys
DUMPKEY_JAR := $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar
$(RECOVERY_INSTALL_OTA_KEYS): PRIVATE_OTA_PUBLIC_KEYS := $(OTA_PUBLIC_KEYS)
$(RECOVERY_INSTALL_OTA_KEYS): $(OTA_PUBLIC_KEYS) $(DUMPKEY_JAR)
@echo "DumpPublicKey: $@ <= $(PRIVATE_OTA_PUBLIC_KEYS)"
@rm -rf $@
@mkdir -p $(dir $@)
java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) > $@

$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
$(INSTALLED_RAMDISK_TARGET) \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(recovery_binary) \
$(recovery_initrc) $(recovery_kernel) \
$(INSTALLED_2NDBOOTLOADER_TARGET) \
$(recovery_build_prop) $(recovery_resource_deps) \
$(recovery_fstab) \
$(RECOVERY_INSTALL_OTA_KEYS)

/* 以正常系统的根文件系统为基础构建 Recovery 的根文件系统 */
@echo ----- Making recovery image ------
rm -rf $(TARGET_RECOVERY_OUT)
mkdir -p $(TARGET_RECOVERY_OUT)
mkdir -p $(TARGET_RECOVERY_ROOT_OUT)
mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc
mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp
echo Copying baseline ramdisk...
cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)

/* 删除所有的 Init 脚本,使用 Recovery 特定的 Init 脚本 */
rm $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
echo Modifying ramdisk contents...
cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/

/* 添加 Recovery Binary */
cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/

/* 添加通用的和设备特定的 Recovery 资源 */
cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/
$(foreach item,$(recovery_resources_private), \
cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)

/* 添加设备特定的文件系统表 */
$(foreach item,$(recovery_fstab), \
cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)
$(foreach item,$(recovery_mmc_fstab), \
cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery_mmc.fstab)

/* 内嵌验证签名的公钥 */
cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys

/* 生成 Recovery 模式的默认属性文件 */
cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
> $(TARGET_RECOVERY_ROOT_OUT)/default.prop

/* 生成 Recovery 的根文件系统 ramdisk-recovery.img */
$(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)

/* 把正常系统的内核跟 ramdisk-recovery.img 打包生成 Recovery Image */
$(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@
@echo ----- Made recovery image -------- $@

/* 验证生成的 Recovery Image 有没有超出 Recovery 分区的大小 */
$(hide) $(call assert-max-image-size,$@,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE),raw)

else
INSTALLED_RECOVERYIMAGE_TARGET :=
endif

.PHONY: recoveryimage
recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET)

  • Recovery Init Script:

  从上面的分析可以看出 recovery.img 和 boot.img 的区别不大,主要是 init 脚本不一样,recovery 的 init 脚本相对简单,系统起来后只运行 ueventd、recovery、adbd 三个服务。

# bootable/recovery/etc/init.rc

on early-init
start ueventd

on init
export PATH /sbin
export ANDROID_ROOT /system
export ANDROID_DATA /data
export EXTERNAL_STORAGE /sdcard

symlink /system/etc /etc

mkdir /sdcard
mkdir /system
mkdir /data
mkdir /cache

mount /tmp /tmp tmpfs

on boot
ifup lo
hostname localhost
domainname localdomain

class_start default

service ueventd /sbin/ueventd
critical

service recovery /sbin/recovery

service adbd /sbin/adbd recovery
disabled

on property:persist.service.adb.enable=1
start adbd

on property:persist.service.adb.enable=0
stop adbd

  • Android <----> Recovery Binary <----> Bootloader:

  有时候 Android 需要不同的模式互相协助来完成一项任务,这样不同模式之间就要有一种机制来交换信息。Recovery Binary 和 Bootloader 之间是通过 misc 分区来传递信息的,如果是 MTD 设备,则使用 misc 分区的第二个页面,如果是块设备,则使用 misc 分区的第一块,交换的信息通过如下结构体封装。Recovery Binary 和 Android 之间是通过 cache 分区下的如下几个固定文件来传递信息的。

/* Recovery Binary <----> Bootloader */

struct bootloader_message {
char command[ 32];
char status[ 32];
char recovery[ 1024];
};

/* Recovery Binary <----> Android */

/cache/recovery/command
/cache/recovery/intent
/cache/recovery/log
/cache/recovery/last_log

  • Updater Binary:

  Updater Binary 是 OTA package 的安装程序,被打包到 OTA package 中一起发布。Updater Binary 的源代码位于目录 bootable/recovery/updater 中。每个设备都可以为 Updater Binary 添加自己特定的扩展,然后通过变量TARGET_RECOVERY_UPDATER_LIBS 和 TARGET_RECOVERY_UPDATER_EXTRA_LIBS 来指定。

# bootable/recovery/updater/Android.mk

LOCAL_STATIC_LIBRARIES  +=  $(TARGET_RECOVERY_UPDATER_LIBS) \
$(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
LOCAL_STATIC_LIBRARIES + = libapplypatch libedify libmtdutils libminzip libz
LOCAL_STATIC_LIBRARIES + = libmincrypt libbz
LOCAL_STATIC_LIBRARIES + = libcutils libstdc++ libc
LOCAL_C_INCLUDES + =  $(LOCAL_PATH)/..

# Each library in TARGET_RECOVERY_UPDATER_LIBS should have a function
# named "Register_<libname>()". Here we emit a little C function that
# gets #included by updater.c. It calls all those registration
# functions.

# Devices can also add libraries to TARGET_RECOVERY_UPDATER_EXTRA_LIBS.
# These libs are also linked in with updater, but we don't try to call
# any sort of registration function for these. Use this variable for
# any subsidiary static libraries required for your registered
# extension libs.

inc := $(call intermediates-dir-for,PACKAGING,updater_extensions)/register.inc

# During the first pass of reading the makefiles, we dump the list of
# extension libs to a temp file, then copy that to the ".list" file if
# it is different than the existing .list (if any). The register.inc
# file then uses the .list as a prerequisite, so it is only rebuilt
# (and updater.o recompiled) when the list of extension libs changes.

junk := $(shell mkdir -p $(dir $(inc));\
echo $(TARGET_RECOVERY_UPDATER_LIBS) > $(inc).temp;\
diff -q $(inc).temp $(inc).list || cp -f $(inc).temp $(inc).list)

$(inc) : libs := $(TARGET_RECOVERY_UPDATER_LIBS)
$(inc) : $(inc).list
$(hide) mkdir -p $(dir $@)
$(hide) echo "" > $@
$(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@)
$(hide) echo "void RegisterDeviceExtensions() {" >> $@
$(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@)
$(hide) echo "}" >> $@

$(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc)
LOCAL_C_INCLUDES += $(dir $(inc))

转载于:https://my.oschina.net/u/183622/blog/77241

Android 的 Recovery 模式分析相关推荐

  1. android 版本更新原理,Android系统Recovery工作原理之使用update.zip升级过程分析(二)...

    Android系统Recovery工作原理之使用update.zip升级过程分析(二)---update.zip差分包问题的解决 在上一篇末尾提到的生成差分包时出现的问题,现已解决,由于最近比较忙,相 ...

  2. Android系统Recovery工作原理之使用update.zip升级过程分析(五)

    Android系统Recovery工作原理之使用update.zip升级过程分析(五)---update.zip包从上层进入Recovery服务文章开头我们就提到update.zip包来源有两种,一个 ...

  3. Android的Recovery中font_10x10.h字库文件制作

    任务是要汉化Android中的Recovery,就了解了bootable/recovery/minui/font_10x18.h这个英文字库的来历,最终汉化的时候并没有自己汉字字库,用的github上 ...

  4. gihosoft android 教程,Gihosoft Free Android Data Recovery

    Gihosoft Free Android Data Recovery官方版是一款专业且高效的安卓手机专用数据恢复工具,Gihosoft Free Android Data Recovery官方版功能 ...

  5. Android系统Recovery工作原理之使用update.zip升级过程分析(二)---u...

    2019独角兽企业重金招聘Python工程师标准>>>  Android系统Recovery工作原理之使用update.zip升级过程分析(二)---update.zip差分包问题的 ...

  6. Android系统Recovery工作原理之使用update.zip升级过程分析(四)

    Android系统Recovery模式的工作原理在使用update.zip包升级时怎样从主系统(main system)重启进入Recovery模式,进入Recovery模式后怎样判断做何种操作,以及 ...

  7. android recovery分区内刷镜像,Android手机Recovery模式取证方法研究.pdf

    Android手机Recovery模式取证方法研究 2015 年第 9 期 信息通信 2015 (总第 153 期) INFORMATION & COMMUNICATIONS (Sum. No ...

  8. Android 的Recovery机制

    Android 的Recovery机制 目录 1. 系统的启动模式 1 1.1 Android系统的启动模式 1 1.2 系统的启动模式 2 2. Recovery模式中的三个部分 3 3. Reco ...

  9. 三星root后进入android system recovery后,三星手机在用刷机大师刷机之后,Android system recoverylt;3egt;,找......

    Android system recovery<3e> 注意看下有3E标志就是官方自带的~~一般官方自带3e的机子不能卡刷,只能线刷~~ Volume up/down to move hi ...

  10. 安卓手机主题软件_安卓手机数据恢复软件——FonePaw Android Data Recovery Mac

    手机数据意外丢失?想要一款安卓手机数据恢复软件?FonePaw Android Data Recovery for Mac推荐给大家!Android Data Recovery Mac版可以从Andr ...

最新文章

  1. jdbc,mybatis,hibernate各自优缺点及区别
  2. 华为内部存储转sd卡_高调谈洗牌 2019年中国存储市场下半场的关键词是“低调”吗?...
  3. 考研计算机专业复试,计算机专业考研复试准备
  4. C# override详解
  5. React开发(242):dva概念6effect
  6. java进程调度怎么画图,[Java教程]进程调度的两种算法JAVA实现
  7. Python学习笔记之类(三)
  8. 弹性地基梁板的计算理论_造价人常用小帮手:30个实用小软件+44套计算表,绝对实用...
  9. 撩妹java代码_Java程序媛深入浅出设计模式中的撩妹神技--中篇
  10. adb命令刷机vivox20_求救VIVO X20的 ROOT可行的方法。
  11. Linux dstat 监控工具
  12. 一、Geos库的安装和计算多边形是否相交
  13. 【脑图制作】万彩脑图大师教程 | 怎么制作思维导图
  14. PC端调用摄像头录制视频——vue标准写法
  15. 【neo4j】去除重复节点
  16. 语句摘抄——第21周
  17. 【推荐】两大APP与云账户红包SDK集成详情及Demon分享
  18. java p41——Filter过滤器
  19. 个人赛 A 题 传球游戏(ball)
  20. 科目二连续失败的反思

热门文章

  1. 记录:添加trace_event埋点并调用
  2. php将一个日期字符串转换成举例来说当前的,PHP将一个日期字符串转换成举例来说当前的天数...
  3. 遇到的问题:uboot下,关闭串口前需要printf打印一个“UART BUS OFF!!!”提示信息,但是打印不出来
  4. system函数 fork函数
  5. 定时器函数执行原理揭秘
  6. A - 饭卡(动态规划 01背包)
  7. F - 小希的迷宫 (并查集)
  8. shell 计算代码运行时间
  9. SLAM笔记------------------(1)
  10. Java复合函数循环_Java函数式编程(一)(示例代码)