1.Recovery模式启动

本文深入探讨了Android的Recovery模式,包括其启动流程、更新包结构以及如何通过main函数、getargs获取参数和prompt_and_wait执行菜单命令。在Recovery模式下,系统通过特定键组合或RecoverySystem进入,并加载专属rc文件。升级包包含boot.img、system、recovery等文件,用于系统更新。解析了bootloader_message结构体的作用,以及getargs如何从misc分区获取启动参数。此外,介绍了finish_recovery函数清理misc分区内容,以及prompt_and_wait函数处理用户输入的逻辑。
摘要由CSDN通过智能技术生成

本章关键点总结 & 说明:

导图是不断迭代的,这里主要关注➕ recovery模式启动部分即可,主要从 更新包简介,mian函数解析开始解读,分析了main函数中关键的方法 获取参数getargs和执行菜单命令prompt_and_wait。

对于recovery模式,一般均采用第三方的方案,比如:在使用MTK平台时,我们这边一般会直接采用广升FOTA的服务商直接进行升级相关的工作。对于第三方的recovery代码,实际上也是参考android原生代码进行改动,核心原理不变,因此这里对recovery模式的代码研究还是采用 google 的原生recovery代码。

android 启动时会通过组合键 判定是否进入recovery模式,也可以通过android的RecoverySystem来进入。recovery模式下还是会启动bootloader、kernel,最后会通过bootargs来判定,如果进入recovery模式则加载recovery专属的rc文件,进而进入到recovery模式。

recovery模式主要是使用升级包进行升级,升级包解压后一般是这样

包含的文件简要说明:

  1. boot.img:更新boot分区所需要的文件。这个boot.img主要包括kernel+ramdisk。
  2. system/  :内容在升级后会放在系统的system分区。主要用来更新系统的一些应用或则应用会用到的一些库
  3. recovery/ :中的recovery-from-boot.p是boot.img和recovery.img的补丁(patch),主要用来更新recovery分区,其中etc/目录下的install-recovery.sh是更新脚本。
  4. META-INF放的是更新包的签名文件和更新脚本,只有更新包的签名和设备签名匹配才能进行系统升级,包含三个关键文件。

 

最后META-INF的几个文件解读如下所示:

  1. CERT.RSA:与签名文件相关联的签名程序块文件,它存储了用于签名JAR文件的公共签名。
  2. CERT.SF:这是JAR文件的签名文件,其中前缀CERT代表签名者。
  3. MANIFEST.MF:manifest文件定义了与包的组成结构相关的数据。
  4. update-binary:二进制文件,相当于脚本解释器,能够识别updater-script中描述的操作。
  5. updater-script:脚本文件,具体描述了更新过程。我们可以根据具体情况编写该脚本来适应我们的具体需求。
  6. metadata:描述设备信息及环境变量的元数据。主要包括一些编译选项,签名公钥,时间戳以及设备型号等。

接下来我们从main函数启动开始分析,到如何传递参数,以及如何执行菜单命令 角度来逐步分析。

1 main函数启动分析

int main(int argc, char **argv) {
    time_t start = time(NULL);
 
    redirect_stdio(TEMPORARY_LOG_FILE);
    if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
        adb_main();//如果参数中有adb,作为adbd的daemon启动
        return 0;
    }
    //读取/etc/recovery.fstab文件,保存了recovery模式下分区情况(名称+参数)
    load_volume_table();
    ensure_path_mounted(LAST_LOG_FILE);
    rotate_last_logs(KEEP_LOG_COUNT);
    //获得启动参数(按照优先级,分别是recovery->misc->/cache/recovery/command中命令)
    get_args(&argc, &argv);
 
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0, show_text = 0;
    bool just_exit = false;
    bool shutdown_after = false;
 
    int arg;
    //解析启动参数
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break; //升级系统
        case 'w': wipe_data = wipe_cache = 1; break; //擦出数据
        case 'c': wipe_cache = 1; break; //擦除cache
        case 't': show_text = 1; break;//指示升级时是否显示UI
        case 'x': just_exit = true; break; //退出
        case 'l': locale = optarg; break; //指定locale
        //...
        case '?':
            LOGE("Invalid command argument\n");
            continue;
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值