fota升级失败小结(recovery.cpp)

本文主要介绍了如何分析FOTA(Firmware Over The Air)升级失败的问题,通过检查recovery.log,使用SourceInsight查看源码,以及可能在/system或/bionic下查找未定义方法。当last_log不完整时,可能需要通过串口抓取完整log,注意串口非USB,可能需要硬件操作。FOTA更新文件通常存储在内部或外部存储的不同路径下。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.查看升级成功和失败的recovery的log,在/cache/recovery/last_log
2.用sourceinsight导入/bootable/recovery,根据log,全局搜索。逐步分析
3.有些没有的方法可能存在/system或者/bionic下。
4.如果没有想要的,可以用串口去在recovery期间抓取完整的log,但是串口不是usb,
需要拆开机器去焊接引出几根串口线,而last_log是不完整的,只有从recovery.cpp的
main函数开始的log,前面的log是没有的。
5.fota的话,一般会把update.zip下载在内置卡或者外置卡设备的挂载点,或者一些存在与内外置卡映射关系。
如:/data/media/0, /storage/emulated/0, /storage/sdcard0, /mnt/storage/0

 

int
main(int argc, char **argv) {
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
 
#ifdef FOTA_UPDATE_SUPPORT     //这个参数一般是成立的,应该是为了适配fota
#else
#ifdef TARGET_RK30
    freopen("/dev/ttyFIQ0", "a", stdout); setbuf(stdout, NULL);
    freopen("/dev/ttyFIQ0", "a", stderr); setbuf(stderr, NULL);
#else
    freopen("/dev/ttyS1", "a", stdout); setbuf(stdout, NULL);
    freopen("/dev/ttyS1", "a", stderr); setbuf(stderr, NULL);
#endif
#endif

    // If this binary is started with the single argument "--adbd",
    // instead of being the normal recovery binary, it turns into kind
    // of a stripped-down version of adbd that only supports the
    // 'sideload' command.  Note this must be a real argument, not
    // anything in the command file or bootloader control block; the
    // only way recovery should be run with this argument is when it
    // starts a copy of itself from the apply_from_adb() function.
    if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
        adb_main();
        return 0;
    }

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

    load_volume_table();//加载/etc/recovery.fstab
	SetSdcardRootPath();
    ensure_path_mounted(LAST_LOG_FILE);
    rotate_last_logs(10);
    get_args(&argc, &argv);//从某个地方将command写到argv指向的地方
    //argv是recovery的重要参数,
    //如:"/sbin/recovery" "--update_package=/storage/emulated/0/adupsfota/update.zip" "--locale=zh_CN"
    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    const char *update_rkimage = NULL;
    char *auto_sdcard_update_path = NULL;
    int wipe_data = 0, wipe_cache = 0, show_text = 0, wipe_all = 0;
    bool just_exit = false;
    int factory_mode_en = 0;
    char *factory_mode = NULL;
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;//如果这个不为null,那么update_rkimage 应该为null。getopt_long方法在bionic文件夹下。
        case 'r':  update_rkimage = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case 'f': factory_mode = optarg;factory_mode_en = 1; break;
        case 't': show_text = 1; break;
        case 'w'+'a':{ wipe_all = wipe_data = wipe_cache = 1;show_text = 1;} break;
        case 'x': just_exit = true; break;
        case 'l': locale = optarg; break;
        case 'g': {
            if (stage == NULL || *stage == '\0') {
                char buffer[20] = "1/";
                strncat(buffer, optarg, sizeof(buffer)-3);
                stage = strdup(buffer);
            }
            break;
        }
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    if (locale == NULL) {
        load_locale_from_cache();
    }
    printf("locale is [%s]\n", locale);
    printf("stage is [%s]\n", stage, stage);

    Device* device = make_device();
    ui = device->GetUI();//recovery 界面相关,就是那些有android机器人的界面
    gCurrentUI = ui;

    ui->Init();

    int st_cur, st_max;
    if (stage != NULL && sscanf(stage, "%d/%d", &st_cur, &st_max) == 2) {
        ui->SetStage(st_cur, st_max);
    }

    ui->SetLocale(locale);
	//ui->SetBackground(RecoveryUI::NONE);
	ui->Print("Recovery system v4.4.0 \n\n");
	printf("Recovery system v4.4.0 \n");
    if (show_text) ui->ShowText(true);

    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        ui->Print("Warning: No file_contexts\n");
    }

    device->StartRecovery();
    SureCacheMount();
    SureMetadataMount();

    //sdcard may not ready,so wait a feel seconds.
    int i;
    for(i = 0; i < 2; i++) {
		if(0 == ensure_path_mounted(EX_SDCARD_ROOT)){
			break;
		}else {
			printf("delay 2sec\n");
			sleep(2);
		}
	}

    //boot from sdcard
    if(!check_sdboot()) {
		printf("find sdfwupdate commandline!\n");
		return sdtool_main(factory_mode, device);
	}else {
		printf("Not enter sdboot!\n");
	}

    //get misc commond factory mode, goto sdtool
    if(factory_mode_en) {
    	printf("find factory mode misc command!\n");
    	ret
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值