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
- 获取参数信息
//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
- 进入升级流程
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;
}