MTK 8.1 recovery_log分析

MTK 8.1 recovery_log分析01

 

本次分析以对应last_log推出recovery主要的执行流程

涉及文件:

bootable/recovery/recovery.cpp

bootable/recovery/install.cpp

bootable/recovery/roots.cpp

cache/recovery_log/last_log

out/target/product/k63v2_64_bsp/recovery/root/etc/recovery.fstab,OBJ包中路径/RECOVERY/RAMDISK/etc/recovery.fstab

 

原生 OTA INSTALL信息

 * OTA INSTALL

 * 1. main system downloads OTA package to /cache/some-filename.zip

 * 2. main system writes "--update_package=/cache/some-filename.zip"

 * 3. main system reboots into recovery

 * 4. get_args() writes BCB with "boot-recovery" and "--update_package=..."

 *    -- after this, rebooting will attempt to reinstall the update --

 * 5. install_package() attempts to install the update

 *    NOTE: the package install must itself be restartable from any point

 * 6. finish_recovery() erases BCB

 *    -- after this, rebooting will (try to) restart the main system --

 * 7. ** if install failed **

 *    7a. prompt_and_wait() shows an error icon and waits for the user

 *    7b. the user reboots (pulling the battery, etc) into the main system

 */

 

 

 

Recovery.cpp

 

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

 

1.加载分区表

printf("Starting recovery (pid %d) on %s", getpid(), ctime(&start));

 

Last_log:Starting recovery (pid 193) on Wed Jun 20 12:04:43 2018

//加载recovery.fstab建立分区表信息  

load_volume_table();

//从建立的分区表信息中读取是否有cache分区,log信息存入cache分区中

has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;

 

Roots.cpp

void load_volume_table(){

 //在last_log中打印分区表信息,顺序为编号,挂载节点,文件系统类型,块设备,长度

    printf("recovery filesystem table\n");

    printf("=========================\n");

    for (i = 0; i < fstab->num_entries; ++i) {

        Volume* v = &fstab->recs[i];

        printf("  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,

               v->blk_device, v->length);

    }

    printf("\n");

}

Last_log:

[    0.004364] recovery filesystem table

[    0.004383] =========================

[    0.004403]   0 /system ext4 /dev/block/platform/mtk-msdc.0/11120000.msdc0/by-name/system 0

[    0.004416]   1 /vendor ext4 /dev/block/platform/mtk-msdc.0/11120000.msdc0/by-name/vendor 0

[    0.004427]   2 /system ext4 /dev/block/platform/mtk-msdc.0/11120000.msdc0/by-name/system 0

.........

[    0.004717]   28 /sdcard_dev2 vfat /dev/block/platform/mtk-msdc.0/11120000.msdc0/by-name/intsd 0

 

  1. 获取参数信息

//get_args方法获取misc分区的command文件

    std::vector<std::string> args = get_args(argc, argv);

    std::vector<char*> args_to_parse(args.size());

    std::transform(args.cbegin(), args.cend(), args_to_parse.begin(),

                   [](const std::string& arg) { return const_cast<char*>(arg.c_str()); });

Last_log: 

I:Boot command: boot-recovery

I:Got 3 arguments from boot message

 

//通过getopt_long方法将command参数转化为字符打印到last_log中

    while ((arg = getopt_long(args_to_parse.size(), args_to_parse.data(), "", OPTIONS,

                              &option_index)) != -1) {

    if (locale.empty()) {

        if (has_cache) {

            locale = load_locale_from_cache();

        }

 

        if (locale.empty()) {

            locale = DEFAULT_LOCALE;

        }

    }

    printf("locale is [%s]\n", locale.c_str());

    printf("stage is [%s]\n", stage.c_str());

    printf("reason is [%s]\n", reason);

 

Last_log:

[    0.032947] locale is [en-US]

[    0.032978] stage is []

[    0.032990] reason is [(null)]

 

//界面显示系统更新,如果有--security界面显示系统安全更新

   ui->SetSystemUpdateText(security_update);

    int st_cur, st_max;

    if (!stage.empty() && sscanf(stage.c_str(), "%d/%d", &st_cur, &st_max) == 2) {

        ui->SetStage(st_cur, st_max);

}

//显示recovery的背景

ui->SetBackground(RecoveryUI::NONE);

//显示recovery的菜单

if (show_text) ui->ShowText(true);

//设置selinux的权限

    sehandle = selinux_android_file_context_handle();

    selinux_android_set_sehandle(sehandle);

    if (!sehandle) {

        ui->Print("Warning: No file_contexts\n");

    }

device->StartRecovery();

//打印command信息

printf("Command:");

 

 

 

Last_log:

[    0.943145] SELinux: Loaded file_contexts

[    0.943218] Command: "/sbin/recovery" "--update_package=/storage/3991-1BE4/Android/data/com.adups.fota/files/adupsfota/update.zip" "--locale=en-US"

//引入FOTA lib路径转换

    //adupsfota start

    #ifdef ADUPS_FOTA_SUPPORT

    if (perform_fota == 1) {

find_update_package_new(update_package);

Last_log:

[    0.943249] E:fota lib version: V1.0.2_20171214

[    0.943261] (replacing path "/storage/3991-1BE4/Android/data/com.adups.fota/files/adupsfota/update.zip" with "/sdcard/Android/data/com.adups.fota/files/adupsfota/update.zip")

 

//打印出手机里的属性信息,所以last_log里的属性值是基础版本中的

    property_list(print_property, NULL);

    printf("\n");

 

    ui->Print("Supported API: %d\n", RECOVERY_API_VERSION);

fprintf(stdout, "update_package = %s\n", update_package ? update_package : "NULL");

 

Last_log:

[    0.944492] persist.mtk.wcn.combo.chipid=-1

[    0.944517] persist.mtk.wcn.patch.version=-1

........

[    0.953494] ro.config.alarm_alert=RingingAlarm.ogg

[    0.953505] ro.config.notification_sound=MyPhone_Tune.ogg

[    0.953516]

[    0.953526] Supported API: 3

[    0.969002] update_package = /sdcard/Android/data/com.adups.fota/files/adupsfota/update.zip

[    0.971334] charge_status 3, charged 0, status 0, capacity 36

  1. 进入升级流程

    int status = INSTALL_SUCCESS;

 

    if (update_package != NULL) {

        // It's not entirely true that we will modify the flash. But we want

        // to log the update attempt since update_package is non-NULL.

        modified_flash = true;

    ......

    } else {

            status = install_package(update_package, &should_wipe_cache,

                                     TEMPORARY_INSTALL_FILE, true, retry_count);

            //adupsfota start

            #ifdef ADUPS_FOTA_SUPPORT

            if (perform_fota == 1) {

                finish_adupsfota(update_package, TEMPORARY_LOG_FILE, status);

        }

            #endif

            //adupsfota end

 

Install.cpp

//具体执行安装在really_install_package方法中

int install_package(const std::string& path, bool* wipe_cache, const std::string& install_file,

                    bool needs_mount, int retry_count) {

 

    result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count,

                                    &max_temperature);

 

 

static int really_install_package(const std::string& path, bool* wipe_cache, bool needs_mount,

                                  std::vector<std::string>* log_buffer, int retry_count,

                                  int* max_temperature) {

//屏幕显示正在更新

  ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);

  ui->Print("Finding update package...\n");

  // Give verification half the progress bar...

//设置进度条的类型

  ui->SetProgressType(RecoveryUI::DETERMINATE);

//显示进度条

  ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);

//log中显示升级的路径

  LOG(INFO) << "Update location: " << path;

 

Last_log:

[    1.020396] Finding update package...

[    1.088289] I:Update location: /sdcard/Android/data/com.adups.fota/files/adupsfota/update.zip

 

  // Map the update package into memory. 映射升级包路径到内存

  ui->Print("Opening update package...\n");

//判断路径是否需要去挂载,带@的路径是加密的data,不带@的是sdcard

  if (needs_mount) {

    if (path[0] == '@') {

      ensure_path_mounted(path.substr(1).c_str());

    } else {

      ensure_path_mounted(path.c_str());

    }

  }

//映射升级包路径到内存

  MemMapping map;

  if (!map.MapFile(path)) {

    LOG(ERROR) << "failed to map file";

    return INSTALL_CORRUPT;

  }

Last_log: [    1.088382] Opening update package...

  // Verify package.  校验升级包,所以校验签名的方法是在install.cpp中verify_package执行

  if (!verify_package(map.addr, map.length)) {

    log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));

    return INSTALL_CORRUPT;

  }

Last_log:

[    1.149501] I:read key e=65537 hash=20

[    1.149677] I:1 key(s) loaded from /res/keys

[    1.149730] Verifying update package...

[    1.160982] I:comment is 1555 bytes; signature is 1537 bytes from end

[    1.649360] I:signature (offset: 8a60c3, length: 5fb): 308205f706092a864886f70d010702a08205e8308205e4020101310b300906052b0e03021a0500300b06092a864886f70d010701a08203f930820[    1.655325] I:whole-file signature verified against RSA key 0

[    1.655373] Update package verification took 0.5 s (result 0).

 

  // Try to open the package.

  ZipArchiveHandle zip;

  int err = OpenArchiveFromMemory(map.addr, map.length, path.c_str(), &zip);

  if (err != 0) {

    LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err);

    log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));

    CloseArchive(zip);

    return INSTALL_CORRUPT;

  }

  // Check partition size between source and target  校验分区表

#ifndef AB_OTA_UPDATER

  int ret=INSTALL_SUCCESS;

  if (mt_really_install_package_check_part_size(ret, path.c_str(), needs_mount, zip)) {

    CloseArchive(zip);

    return ret;

  }

#endif

 

Last_log:

[    1.684768] ====== Scatter File:

[    1.684832] preloader 0x0

.......

.......

[    1.685539] userdata 0x7e000000

[    1.685571] mt_is_support_gpt gpt prefix is /dev/block/platform/mtk-msdc.0/11120000.msdc0/by-name

[    1.685596] is_gpt = 1

[    1.685619] gpt prefix is /dev/block/platform/mtk-msdc.0/11120000.msdc0/by-name

[    1.703289] Parse Partition sucessfully

 

  // Additionally verify the compatibility of the package.

  if (!verify_package_compatibility(zip)) {

    log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));

    CloseArchive(zip);

    return INSTALL_CORRUPT;

  }

 

Last_log:

[    1.703340] I:Verifying package compatibility...

[    1.703393] I:Package doesn't contain compatibility.zip entry

 

  // Verify and install the contents of the package.

  ui->Print("Installing update...\n");

  if (retry_count > 0) {

    ui->Print("Retry attempt: %d\n", retry_count);

  }

  ui->SetEnableReboot(false);

//具体执行升级的地方

  int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);

  ui->SetEnableReboot(true);

  ui->Print("\n");

 

Last_log:

[    1.703416] Installing update...

[    1.771248] platform fs_type: EMMC

[    1.771299] ====== Updater-Script:

.........

 

  CloseArchive(zip);

  return result;

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值