首页 > 系统相关 >Rockchip RK3588 - Rockchip Linux Recovery recovery源码分析

Rockchip RK3588 - Rockchip Linux Recovery recovery源码分析

时间:2024-10-06 21:24:01浏览次数:1  
标签:buildroot Recovery rk3588 Rockchip package update 源码 armsom recovery

----------------------------------------------------------------------------------------------------------------------------

开发板 :ArmSoM-Sige7开发板
eMMC64GB
LPDDR48GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot2017.09
linux5.10
----------------------------------------------------------------------------------------------------------------------------

在《Rockchip RK3588 - Rockchip Linux Recovery updateEngine源码分析》中我们对updateEngine源码进行了深入分析,并提到updateEngine 升级命令由两部分组成;

  • normal系统下的升级:升级recovery分区,并修改misc分区,重启系统;
  • recovery系统下的升级:系统重启之后,会根据misc分区存放的字段来判断将要引导的系统是normal系统还是recovery系统,这里会进入到recovery系统,进行剩余分区的升级;

其中normal系统下的升级是通过updateEngine可执行程序完成的;

// 1. 在normal系统,updateEngine升级recovery分区;升级完函数就返回了,并不会升级其它分区
main(argc, argv)
	MiscUpdate(image_url, partition, save_path)		
		//  对需要执行的升级命令打标记(这里标记了parameter、recovery升级命令)
		RK_ota_set_partition(0x040000)   
		// 进行parameter、recovery分区升级
		RK_ota_start(handle_upgrade_callback, handle_print_callback)
		// 往misc偏移16k位置写入recovery信息,这样系统重启后会进入recovery系统执行剩余分区的升级
		set_bootloader_message(&msg)
		
	// 2. 触发系统重启
	system(" echo b > /proc/sysrq-trigger ")

recovery系统下的升级,是通过recovery可执行程序实现,recovery二进制bin程序部会根据编译配置调用updateEngine或者rkupdate进行升级,本章的目标就是对recovery源码进行分析。

一、recovery目标分析

1.1 目标recovery

定位到<Rockchip Linux SDK>/external/recovery目录下的Makefile文件,找到目标recovery;

OBJ = recovery.o \
        default_recovery_ui.o \
        rktools.o \
        roots.o \
        bootloader.o \
        safe_iop.o \
        strlcpy.o \
        strlcat.o \
        rkupdate.o \
        sdboot.o \
        usbboot.o \
        mtdutils/mounts.o \
        mtdutils/mtdutils.o \
        mtdutils/rk29.o \
        minzip/DirUtil.o \
        update_engine/log.o

ifdef RecoveryNoUi  
OBJ += noui.o      # 不走这里
else
OBJ += ui.o\       # 走这里  
        minzip/Hash.o \
        minzip/SysUtil.o \
        minzip/Zip.o \
        minui/events.o \
        minui/graphics.o \
        minui/resources.o \
        minui/graphics_drm.o
endif

CFLAGS += -I$(PROJECT_DIR) -I/usr/include -I/usr/include/libdrm/ -lc -DUSE_UPDATEENGINE=ON

ifdef RecoveryNoUi
CFLAGS += -lpthread -lbz2        # 不走这里
else
CFLAGS += -lz -lpng -ldrm -lpthread -lcurl -lcrypto -lbz2   # 走这里  
endif

$(PROM): $(OBJ)
        $(CC) -o $(PROM) $(OBJ) $(CFLAGS)

可以看到目标recovery是由若干个.o文件通过aarch64-buildroot-linux-gnu-gcc编译器链接生成的可执行文件。

.o文件实际上是由.c文件通过aarch64-buildroot-linux-gnu-gcc编译器编译生成的。

# build in buildroot, it need change work directory
recovery_version:
        cd $(PROJECT_DIR)/../../../../../external/recovery && \
        COMMIT_HASH=$$(git rev-parse --verify --short HEAD) && \
        GIT_COMMIT_TIME=$$(git log -1 --format=%cd --date=format:%y%m%d) && \
        GIT_DIRTY=$$(git diff-index --quiet HEAD -- || echo "-dirty") && \
        commit_info=-g$${COMMIT_HASH}-$${GIT_COMMIT_TIME}$${GIT_DIRTY} && \
        cd $(PROJECT_DIR) && \
        echo "#define GIT_COMMIT_INFO $${commit_info}" > recovery_autogenerate.h

%.o: %.cpp
        $(CC) -c $< -o $@ $(CFLAGS)

%.o: %.c recovery_version
        $(CC) -c $< -o $@ $(CFLAGS)

其中:%.o 表示所有以.o结尾的文件作为目标文件,%.cpp 表示所有以.c结尾的文件作为依赖文件。

程序的入口为update_engine/main.cpp文件。

1.2 编译

在《Rockchip RK3588 - Rockchip Linux SDK Buildroot文件系统构建》中介绍过buildroot编译命令;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot$ sudo make -j8

或者使用如下命令单独编译recovery软件包:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot$ sudo make recovery-dirclean
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot$ sudo make recovery

其中recovery编译日志如下:

>>> recovery develop Syncing from source dir /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/../external/recovery
rsync -au --chmod=u=rwX,go=rX  --exclude .svn --exclude .git --exclude .hg --exclude .bzr --exclude CVS /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/../external/recovery/ /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop
>>> recovery develop Configuring
>>> recovery develop Building
PATH="/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/bin:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin" /usr/bin/make  -C /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop CC="/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/bin/aarch64-buildroot-linux-gnu-gcc" CFLAGS="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os -g0 -D_FORTIFY_SOURCE=1 -I. -fPIC -lpthread -lcurl -lssl -lcrypto -lbz2 -lpng -ldrm -lz -lm -I/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/libdrm -DUSE_UPDATEENGINE=ON -DSUCCESSFUL_BOOT=ON"
make[1]: 进入目录“/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop”
cd /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop/../../../../../external/recovery && \
COMMIT_HASH=$(git rev-parse --verify --short HEAD) && \
GIT_COMMIT_TIME=$(git log -1 --format=%cd --date=format:%y%m%d) && \
GIT_DIRTY=$(git diff-index --quiet HEAD -- || echo "-dirty") && \
commit_info=-g${COMMIT_HASH}-${GIT_COMMIT_TIME}${GIT_DIRTY} && \
cd /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop && \
echo "#define GIT_COMMIT_INFO ${commit_info}" > recovery_autogenerate.h
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/bin/aarch64-buildroot-linux-gnu-gcc -c recovery.c -o recovery.o -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os -g0 -D_FORTIFY_SOURCE=1 -I. -fPIC -lpthread -lcurl -lssl -lcrypto -lbz2 -lpng -ldrm -lz -lm -I/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/libdrm -DUSE_UPDATEENGINE=ON -DSUCCESSFUL_BOOT=ON
......
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/bin/aarch64-buildroot-linux-gnu-gcc -o updateEngine mtdutils/mounts.o mtdutils/mtdutils.o mtdutils/rk29.o update_engine/rkbootloader.o update_engine/download.o update_engine/flash_image.o update_engine/log.o update_engine/main.o update_engine/md5sum.o update_engine/rkimage.o update_engine/rktools.o update_engine/rkboot.o update_engine/crc.o update_engine/update.o update_engine/do_patch.o -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os -g0 -D_FORTIFY_SOURCE=1 -I. -fPIC -lpthread -lcurl -lssl -lcrypto -lbz2 -lpng -ldrm -lz -lm -I/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/libdrm -DUSE_UPDATEENGINE=ON -DSUCCESSFUL_BOOT=ON
make[1]: 离开目录“/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop”
>>> recovery develop Installing to target
/usr/bin/install -D -m 755 /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop/recovery /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/target/usr/bin/
mkdir -p /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/target/res/images
cp /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop/res/images/* /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/target/res/images/
/usr/bin/install -D -m 755 /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/recovery-develop/updateEngine /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/target/usr/bin/
/usr/bin/install -D -m 755 package/rockchip/recovery//S40recovery /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/target/etc/init.d/S40recovery

二、recovery源码分析

recovery程序的入口为recovery.c文件。recovery.c代码比较长,如下所示:

点开查看详情
int
main(int argc, char **argv)
{
    bool bSDBoot    = false;
    bool bUDiskBoot = false;
    const char *sdupdate_package = NULL;
    const char *usbupdate_package = NULL;
    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    const char *encrypted_fs_mode = NULL;
    int wipe_data = 0;
    int wipe_all = 0;
    int pcba_test = 0;  // add for pcba test
    int toggle_secure_fs = 0;
    int arg;
    bool isrkdebug = false;
    int log_level = LOG_DEBUG;
    encrypted_fs_info encrypted_fs_data;
    struct timeval start_time, end_time;
    long long elapsed_time;

    gettimeofday(&start_time, NULL);
    
    get_args(&argc, &argv);
    strcpy(systemFlag, "false");
    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;
        case 'w':
            wipe_data = 1;
            break;
        case 'a':
            wipe_all = 1;
            break;
        case 'e':
            encrypted_fs_mode = optarg;
            toggle_secure_fs = 1;
            break;
        case 't':
            ui_show_text(1);
            break;
        case 'f':
            pcba_test = 1;
            break;  // add for pcba test
        case 'r':
            isrkdebug = true;
            break;
        case 'i':
            gr_set_rotate(atoi(optarg));
            break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }
    
    time_t start = time(NULL);
    if ((access("/.rkdebug", F_OK) != 0) && (isrkdebug != true)) {
        // If these fail, there's not really anywhere to complain...
        if (freopen(TEMPORARY_LOG_FILE, "a", stdout) == NULL) {
            LOGW("freopen stdout error");
        }
        setbuf(stdout, NULL);
        if (freopen(TEMPORARY_LOG_FILE, "a", stderr) == NULL) {
            LOGE("freopen stderr error");
        }
        setbuf(stderr, NULL);
    }
    
    printf("\n");
    printf("*********************************************************\n");
    printf("            ROCKCHIP recovery system                     \n");
    printf("*********************************************************\n");
    printf("**** version : %s ****\n", recovery_version);
    
    LOGI("Starting recovery on %s\n", ctime(&start));
    while (access(coldboot_done, F_OK) != 0) {
        LOGI("coldboot not done, wait...\n");
        sleep(1);
    }

#ifndef RecoveryNoUi
    LOGI("Recovery System have UI defined.\n");
#endif

    ui_init();
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    load_volume_table();
    setFlashPoint();
    
    bSDBoot = is_boot_from_SD();
    bUDiskBoot = is_boot_from_udisk();
    
    if (bSDBoot || bUDiskBoot) {
        char imageFile[64] = {0};
        if (bSDBoot) {
            if (is_sdcard_update()) {
                strlcpy(imageFile, EX_SDCARD_ROOT, sizeof(imageFile));
                strlcat(imageFile, "/sdupdate.img", sizeof(imageFile));
                if (access(imageFile, F_OK) == 0) {
                    sdupdate_package = strdup(imageFile);
                    bSDBootUpdate = true;
                    ui_show_text(1);
                    LOGI("sdupdate_package = %s\n", sdupdate_package);
                }
            }
        }
    
        if (bUDiskBoot) {
            if (is_udisk_update()) {
                strlcpy(imageFile, EX_UDISK_ROOT, sizeof(imageFile));
                strlcat(imageFile, "/sdupdate.img", sizeof(imageFile));
                if (access(imageFile, F_OK) == 0) {
                    usbupdate_package = strdup(imageFile);
                    bUdiskUpdate = true;
                    ui_show_text(1);
                    LOGI("usbupdate_package = %s\n", usbupdate_package);
                }
            }
        }
    }
    
    device_recovery_start();
    
    LOGI("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");
    
    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package + 6, len);
            LOGI("(replacing path \"%s\" with \"%s\")\n",
                 update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");
    
    int status = INSTALL_SUCCESS;
    
    if (toggle_secure_fs) {
        if (strcmp(encrypted_fs_mode, "on") == 0) {
            encrypted_fs_data.mode = MODE_ENCRYPTED_FS_ENABLED;
            ui_print("Enabling Encrypted FS.\n");
        } else if (strcmp(encrypted_fs_mode, "off") == 0) {
            encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED;
            ui_print("Disabling Encrypted FS.\n");
        } else {
            ui_print("Error: invalid Encrypted FS setting.\n");
            status = INSTALL_ERROR;
        }
    
        // Recovery strategy: if the data partition is damaged, disable encrypted file systems.
        // This preventsthe device recycling endlessly in recovery mode.
        if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) &&
            (read_encrypted_fs_info(&encrypted_fs_data))) {
            ui_print("Encrypted FS change aborted, resetting to disabled state.\n");
            encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED;
        }
    
        if (status != INSTALL_ERROR) {
            if (erase_volume("/userdata")) {
                ui_print("Data wipe failed.\n");
                status = INSTALL_ERROR;
#if 0
            } else if (erase_volume("/cache")) {
                ui_print("Cache wipe failed.\n");
                status = INSTALL_ERROR;
#endif
            } else if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) &&
                       (restore_encrypted_fs_info(&encrypted_fs_data))) {
                ui_print("Encrypted FS change aborted.\n");
                status = INSTALL_ERROR;
            } else {
                ui_print("Successfully updated Encrypted FS.\n");
                status = INSTALL_SUCCESS;
            }
        }
    } else if (update_package != NULL) {
        int i, ret = 0;
        const char* binary = "/usr/bin/rkupdate";

        rockchip_partition_check();
    
        for (i = 0; i < 5; i++) {
            if (!ensure_path_mounted(update_package)) {
                LOGI("mounted %s Success.\n", update_package);
                break;
            }
            LOGW("mounted %s Failed. retry %d\n", update_package, i + 1);
            sleep(1);
        }
        if (i != 5) {
            LOGI(">>>rkflash will update from %s\n", update_package);
#ifdef USE_RKUPDATE
            status = do_rk_update(binary, update_package);
#endif
#ifdef USE_UPDATEENGINE
            const char* updateEnginebin = "/usr/bin/updateEngine";
            status = do_rk_updateEngine(updateEnginebin, update_package);
#endif
            if (status == INSTALL_SUCCESS) {
                strcpy(systemFlag, update_package);
                /* update success, delete update.img. */
                if (access(update_package, F_OK) == 0)
                    remove(update_package);
                ui_print("update.img images success!\n");
            } else {
                ui_print("update.img images failed!\n");
            }
        } else {
            LOGE("mounted %s Failed.\n", update_package);
            ui_print("mounted %s Failed.\n", update_package);
        }

        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
        ui_print("update.img Installation done.\n");
        //ui_show_text(0);
    } else if (sdupdate_package != NULL) {
        rockchip_partition_check();
    
        // update image from sdcard
#ifdef USE_RKUPDATE
        const char* binary = "/usr/bin/rkupdate";
        LOGI(">>>sdboot update will update from %s\n", sdupdate_package);
        status = do_rk_update(binary, sdupdate_package);
#endif

#ifdef USE_UPDATEENGINE
#undef FACTORY_FIRMWARE_IMAGE
#undef CMD4RECOVERY_FILENAME
#define FACTORY_FIRMWARE_IMAGE "/mnt/sdcard/out_image.img"
#define CMD4RECOVERY_FILENAME "/mnt/sdcard/cmd4recovery"
        if ((access(FACTORY_FIRMWARE_IMAGE, F_OK)) && access(CMD4RECOVERY_FILENAME, F_OK)) {
            int tmp_fd = creat(CMD4RECOVERY_FILENAME, 0777);
            if (tmp_fd < 0) {
                LOGE("creat %s error.\n", CMD4RECOVERY_FILENAME);
                status = INSTALL_ERROR;
            } else {
                close(tmp_fd);
                const char* updateEnginebin = "/usr/bin/updateEngine";
                status = do_rk_updateEngine(updateEnginebin, sdupdate_package);
            }
        }

        if (isMtdDevice()) {
            LOGI("start flash write to /dev/mtd0.\n");
            size_t total_size;
            size_t erase_size;
            mtd_scan_partitions();
            const MtdPartition *part = mtd_find_partition_by_name("rk-nand");
            if ( part == NULL ) {
                part = mtd_find_partition_by_name("spi-nand0");
            }
            if (part == NULL || mtd_partition_info(part, &total_size, &erase_size, NULL)) {
                if ((!access(FACTORY_FIRMWARE_IMAGE, F_OK)) && mtd_find_partition_by_name("sfc_nor") != NULL) {
                    LOGI("Info: start flash out_image.img to spi nor.\n");
                    system("flashcp -v " FACTORY_FIRMWARE_IMAGE " /dev/mtd0");
                } else
                    LOGE("Error: Can't find rk-nand or spi-nand0.\n");
            } else {
                system("flash_erase /dev/mtd0 0x0 0");
                system("sh "CMD4RECOVERY_FILENAME);
            }
        } else {
            LOGI("Start to dd data to emmc partition.\n");
            system("sh "CMD4RECOVERY_FILENAME);
            LOGI("sdcard upgrade done\n");
        }

#endif

        if (status == INSTALL_SUCCESS) {
            LOGI("update.img Installation success.\n");
            ui_print("update.img Installation success.\n");
            //ui_show_text(0);
        }
    
    } else if (usbupdate_package != NULL) {
        rockchip_partition_check();
        // update image from udisk
#ifdef USE_RKUPDATE
        const char* binary = "/usr/bin/rkupdate";
        LOGI(">>>sdboot update will update from %s\n", usbupdate_package);
        status = do_rk_update(binary, usbupdate_package);
#endif

#ifdef USE_UPDATEENGINE
#undef FACTORY_FIRMWARE_IMAGE
#undef CMD4RECOVERY_FILENAME
#define FACTORY_FIRMWARE_IMAGE "/mnt/usb_storage/out_image.img"
#define CMD4RECOVERY_FILENAME "/mnt/usb_storage/cmd4recovery"
        if ((access(FACTORY_FIRMWARE_IMAGE, F_OK)) && access(CMD4RECOVERY_FILENAME, F_OK)) {
            int tmp_fd = creat(CMD4RECOVERY_FILENAME, 0777);
            if (tmp_fd < 0) {
                LOGE("creat %s error.\n", CMD4RECOVERY_FILENAME);
                status = INSTALL_ERROR;
            } else {
                close(tmp_fd);
                const char* updateEnginebin = "/usr/bin/updateEngine";
                status = do_rk_updateEngine(updateEnginebin, usbupdate_package);
            }
        }

        if (isMtdDevice()) {
            LOGI("start flash write to /dev/mtd0.\n");
            size_t total_size;
            size_t erase_size;
            mtd_scan_partitions();
            const MtdPartition *part = mtd_find_partition_by_name("rk-nand");
            if ( part == NULL ) {
                part = mtd_find_partition_by_name("spi-nand0");
            }
            if (part == NULL || mtd_partition_info(part, &total_size, &erase_size, NULL)) {
                if ((!access(FACTORY_FIRMWARE_IMAGE, F_OK)) && mtd_find_partition_by_name("sfc_nor") != NULL) {
                    LOGI("Info: start flash out_image.img to spi nor.\n");
                    system("flashcp -v " FACTORY_FIRMWARE_IMAGE " /dev/mtd0");
                } else
                    LOGE("Error: Can't find rk-nand or spi-nand0.\n");
            } else {
                system("flash_erase /dev/mtd0 0x0 0");
                system("sh "CMD4RECOVERY_FILENAME);
            }
        } else {
            LOGI("Start to dd data to emmc partition.\n");
            system("sh "CMD4RECOVERY_FILENAME);
            LOGI("usb upgrade done\n");
        }
#endif

        if (status == INSTALL_SUCCESS) {
            LOGI("update.img Installation success.\n");
            ui_print("update.img Installation success.\n");
            //ui_show_text(0);
        }
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/userdata")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_all) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/userdata")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            ui_print("Data wipe failed.\n");
            LOGE("userdata wipe failed.\n");
        } else {
            ui_print("Data wipe done.\n");
            LOGI("userdata wipe done.\n");
        }
    
        //ui_show_text(0);
    } else if (pcba_test) {
        //pcba test todo...
        printf("------------------ pcba test start -------------\n");
        exit(EXIT_SUCCESS); //exit recovery bin directly, not start pcba here, in rkLanuch.sh
        return 0;
    } else {
        if (argc == 1) { // No command specified
            if (!bSDBootUpdate && !bUdiskUpdate && ui_text_visible())
                prompt_and_wait();
            finish_recovery(NULL);
            reboot(RB_AUTOBOOT);
            return 0;
        }
        status = INSTALL_ERROR;  // No command specified
    }
    
    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS) {
        LOGE("\n Install fail! \n");
        if (!bSDBootUpdate && !bUdiskUpdate && ui_text_visible())
            prompt_and_wait();
    }
    
    if (sdupdate_package != NULL && bSDBootUpdate) {
        if (status == INSTALL_SUCCESS) {
            char *SDDdevice =
                strdup(get_mounted_device_from_path(EX_SDCARD_ROOT));
    
            ensure_ex_path_unmounted(EX_SDCARD_ROOT);
            /* Updating is finished here, we must print this message
             * in console, it shows user a specific message that
             * updating is completely, remove SD CARD and reboot */
            fflush(stdout);
            freopen("/dev/console", "w", stdout);
            LOGI("\nPlease remove SD CARD!!!, wait for reboot.\n");
            ui_print("Please remove SD CARD!!!, wait for reboot.");
    
            while (access(SDDdevice, F_OK) == 0) { sleep(1); }
            free(SDDdevice);
        }
    } else if (usbupdate_package && bUdiskUpdate) {
        if (status == INSTALL_SUCCESS) {
            char *udiskDev = strdup(get_mounted_device_from_path(EX_SDCARD_ROOT));
            ensure_path_unmounted(EX_UDISK_ROOT);
            /* Updating is finished here, we must print this message
             * in console, it shows user a specific message that
             * updating is completely, remove U-disk and reboot */
            fflush(stdout);
            freopen("/dev/console", "w", stdout);
            LOGI("\nPlease remove U DISK!!!, wait for reboot.\n");
            ui_print("Please remove U DISK!!!, wait for reboot.");
    
            while (access(udiskDev, F_OK) == 0) { sleep(1); }
            free(udiskDev);
        }
    }
    
    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    gettimeofday(&end_time, NULL);
    
    elapsed_time = (end_time.tv_sec - start_time.tv_sec) * 1000LL +
                   (end_time.tv_usec - start_time.tv_usec) / 1000LL;
    LOGI("recovery usage time:%lld ms\n", elapsed_time);
    ui_print("Rebooting...\n");
    LOGI("Reboot...\n");
    ui_show_text(0);
    fflush(stdout);
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}

参考文章:

[1] Rockchip RK3588 - Rockchip Linux Recovery updateEngine源码分析

[2] Rockchip RK3588 - Rockchip Linux Recovery updateEngine测试

标签:buildroot,Recovery,rk3588,Rockchip,package,update,源码,armsom,recovery
From: https://www.cnblogs.com/zyly/p/18449422

相关文章

  • jsp测试缺陷管理系统3166o程序+源码+数据库+调试部署+开发环
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景随着软件行业的迅速发展,软件质量成为企业竞争力的关键因素。在软件开发过程中,测试缺陷管理系统是确保软件质量的重要环节。传统的缺陷......
  • 写真打赏系统源码无加密无授权无后门
    网站更新写真打赏系统源码版本可对接易支付前端可对接付费进群系统男粉经济变现神器!源码下载:HC网络搭建教学:【2024最新写真打赏系统,写真系统源码搭建教学-哔哩哔哩】 ......
  • 婚恋交友系统源码支持微信小程序 + 微信公众号 + H5 + APP
    婚恋交友系统源码小程序:开启你的浪漫之旅在这个快节奏的时代,寻找真爱似乎变成了一项挑战。但有了我们的婚恋交友系统源码小程序,这一切都将变得简单而美好。这款小程序源码专为追求真挚情感的单身男女设计,集成了多种实用功能,旨在为用户提供一个安全、便捷、高效的在线交友平台......
  • (系列五).net8 中使用Dapper搭建底层仓储连接数据库(附源码)
    说明  该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。   该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。   说明:OverallAuth2.0是一个简单、易懂、功能强大的权限+可视化流程管理系统。友情提醒:本篇文章是属于系......
  • HIS系统,HIS系统源码
    HIS系统在医院信息化建设中扮演着核心的角色。它是一个综合性的信息系统,旨在管理和运营医院的各种业务,包括门诊、住院、财务、物资、科研等。HIS系统的整体组成门诊管理:包括挂号、排班、收费结算等功能。住院管理:包括患者入院、出院、床位管理、医嘱执行等。药房管理:包括药品库存管......
  • 基于微信小程序的大学生就业平台-计算机毕业设计源码+LW文档
    摘要随着计算机技术的成熟,互联网的建立,如今,PC平台上有许多关于大学生就业方面的程序,但由于使用时间和地点上的限制,用户在使用上存在着种种不方便,而开发一款大学生就业平台微信小程序,能够有效地解决这个问题。本文主要介绍了大学生就业平台微信小程序的开发过程,对开发环境、系统......
  • idea源码学习记录-vfs
    参考https://plugins.jetbrains.com/docs/intellij/virtual-file-system.html注:我写笔记用的源码版本是232.8660.185我的idea版本为241.17011.79当前的官方文档用的版本是242.23339.11vfs是idea的虚拟文件系统(VirtualFileSystem)TheVirtualFileSystem(VFS)isa......
  • 基于SpringBoot+Vue+协同过滤算法的音乐推荐系统设计与实现(源码+论文+PPT+部署文档教
    具体实现截图网站首页页面主要包括系统首页、热门歌曲、音乐资讯、留言板、个人中心等内容,并根据需要进行详细操作;如图5-1所示:图5-1网站首页界面图在注册流程中,用户在Vue前端填写必要信息(如用户名、密码等)并提交。前端将这些信息通过HTTP请求发送到Java后端。后端处理......
  • freeRTOS源码解析4--tasks.c 7
    4.2.20空闲任务调用1--prvCheckTasksWaitingTermination删除所有终止的任务,释放资源。简单描述就是清空xTasksWaitingTermination列表,释放资源,递减uxCurrentNumberOfTasks和uxDeletedTasksWaitingCleanUp。接口:staticvoidprvCheckTasksWaitingTermination(void)接口代码如......
  • java+vue计算机毕设防疫工作人员管理系统【源码+程序+论文+开题】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着全球公共卫生事件的频发,防疫工作已成为维护社会稳定和人民健康的关键环节。防疫工作人员作为抗击疫情的前线力量,其管理和调度直接关系到疫情防控......