恢复出厂设置



恢复出厂设置模式—擦除分区

一、Android中的分区 2

二、恢复出厂设置 3

2.1recovery模式下的init.rc 3

2.2recovery.c(入口函数) 3

三、擦除datacache分区 5

总结: 5

 

恢复出厂设置最终会进入Recovery模式,擦除datacache分区之后,系统重启,开始正常的启动流程。

上层从点击事件开始click“恢复出厂设置”,在底层判断节点之后进入恢复出厂设置模式。前面有写过关机流程的文章,当关机或重启的时候,一般都会向相关文件写入命令及原因。恢复出厂设置也不例外,它也会通过写入命令,再去执行相关操作。

此篇文档主要分析的是恢复出厂设置关于底层的流程。在进入主题之前,我们先来了解一下Android中的“分区”概念。

一、Android中的分区

二、恢复出厂设置

当判断出来恢复出厂设置的节点后,它会:1、进入Recovery模式(此模式下可以对内部数据或系统进行修改);2、读取/cache/recovery/command, 命令字段为"--wipe_data";3、按照读取的command,进行清除数据操作(擦除cachedata分区);4、清除成功后系统重启,重新使用system分区的内容完成开机初始化, 进入正常开机流程。

2.1recovery模式下的init.rc

path:./bootable/recovery/etc/init.rc

service recovery /sbin/recovery

    seclabel u:r:recovery:s0

 

service adbd /sbin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery

    disabled

    socket adbd stream 660 system system

seclabel u:r:adbd:s0

 

Note:实质是kernel加载recovery.img,kernel起来后执行的第一个进程就 是init,此进程会读入init.rc启动相应的服务。在recovery模式中,启动的服务是执行recovery可执行文件。

2.2recovery.c(入口函数)

int main(int argc, char **argv) {

 

/* 如果二进制文件使用单个参数"--adbd"启动,而不是正常的recovery启动(不带参数即为正常启动)*/

 if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {

        adb_main(0, DEFAULT_ADB_PORT);

        return 0;

    }

 .............

load_volume_table(); //加载并建立分区表

 .............

 get_args(&argc, &argv); //从传入的参数或/cache/recovery/command文件中得到相应的命令

 while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {

        switch (arg) {

 /*循环解析command或者传入的参数,并把对应的功能设置为true或给相应的变量赋值*/

 ..............

 case 'i': send_intent = optarg; break;

 ..............}

 

 Device* device = make_device();  //初始化UI

    ui = device->GetUI();

    gCurrentUI = ui;

  .............

 ui->SetBackground(RecoveryUI::NONE);//设置recovery界面背景

 .............

 if (show_text) ui->ShowText(true); //设置界面上是否能够显示字符,使能ui->print函数开关

 struct selinux_opt seopts[] = {   // 设置selinux权限

   { SELABEL_OPT_PATH, "/file_contexts" }

 };

//之后开始一些列的安装,清除的操作

status = install_package()//安装升级包

.....

}

 

Note:  1)、get_args()方法得到命令之后,先判断传进来的参数;如果有解析传入的命令,从/cache/recovery/command文件中解析命令。

注意:此函数会先把struct bootloader_message boot写入到misc分区,目的是防止断电等原因导致关机,开机后lk会从misc分区中读取相关信息,如果发现是"boot-recovery"会再次进入recovery模式,misc分区会在退出recovery时被清除,以至于可以正常开机,如果手机每次都是进入recovery而不能正常开机,可以分析是否没有清除misc分区。)

 

2)、 install_package()流程:

1).设置ui界面,包括背景和进度条

 

2).检查是否挂在tmpcachetmp存放升级logcache存放升级包

 

3).加载密钥并校验升级包,防止升级包被用户自己修改

 

  1. .打开升级包,并执行升级包内的安装程序

     

    注:关于Recovery的内容还有很多,这里只是简单的介绍了一些和恢复出厂设置时相关的重要函数而已。

     

    最后:函数 get_args() 会读取 /cache/recovery/command 文件,并根据命令字段进行相应操作,所以它会擦除 data cache 分区:

     erase_volume()  reformats /data

     erase_volume()  reformats /cache

三、擦除datacache分区

//擦除data分区

bool wipe_data(int confirm, Device* device) {

    return mt_wipe_data(confirm, device);

}

//擦除cache分区

static bool wipe_cache(bool should_confirm, Device* device) {

    if (!has_cache) {

        ui->Print("No /cache partition found.\n");

        return false;

    }

    if (should_confirm && !yes_no(device, "Wipe cache?", "  THIS CAN NOT BE UNDONE!")) {

        return false;

    }

    modified_flash = true;

    ui->Print("\n-- Wiping cache...\n");

    bool success = erase_volume("/cache");

    ui->Print("Cache wipe %s.\n", success ? "complete" : "failed");

    return success;

}

总结:恢复出厂设置的流程大致下图所示~

你可能感兴趣的:(恢复出厂设置)