Rockchip RK3588 - Rockchip Linux Recovery recovery源码分析

news/2024/10/6 21:22:55/文章来源:https://www.cnblogs.com/zyly/p/18449422

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

开发板 :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.oifdef 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
endifCFLAGS += -I$(PROJECT_DIR) -I/usr/include -I/usr/include/libdrm/ -lc -DUSE_UPDATEENGINE=ONifdef 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 testint 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 testcase '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 RecoveryNoUiLOGI("Recovery System have UI defined.\n");
#endifui_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_RKUPDATEstatus = do_rk_update(binary, update_package);
#endif
#ifdef USE_UPDATEENGINEconst char* updateEnginebin = "/usr/bin/updateEngine";status = do_rk_updateEngine(updateEnginebin, update_package);
#endifif (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_RKUPDATEconst 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");} elseLOGE("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");}#endifif (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_RKUPDATEconst 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");} elseLOGE("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");}
#endifif (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.shreturn 0;} else {if (argc == 1) { // No command specifiedif (!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测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809214.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解异常和中断(Cortex-M3)

异常和中断的深入了解对于调试很有用,也非常有助于对RTOS的理解,本文是阅读Cortex-M3权威指南和ST、ARM的技术文档,总结出比较精炼的文档。中断一般是由硬件(如外设和外部输入引脚)产生的事件。异常一般指CPU内部产生的打断。但是,也可以把中断称为一种异常我们一般称为系…

深入理解异常和中断

异常和中断的深入了解对于调试很有用,也非常有助于对RTOS的理解,本文是阅读Cortex-M3权威指南和ST、ARM的技术文档,总结出比较精炼的文档。系统异常和外部中断中断一般是由硬件(如外设和外部输入引脚)产生的事件。异常一般指CPU内部产生的打断。但是,也可以把中断称为一种…

ch被动扫描学习

在渗透测试中,被动扫描就像斥候一样担任前驱搜查的任务,帮助后续的渗透攻击等的深入推进提供十分重要的信息。当然,正如一双锐利的眼和好的侦查工具是一名优秀侦察兵的标配,在进行渗透测试的时候,优秀的搜索引擎就是信息收集者的”夜行衣”和“望远镜”。借助它们我们可以…

Nuxt.js 应用中的 app:suspense:resolve 钩子详解

title: Nuxt.js 应用中的 app:suspense:resolve 钩子详解 date: 2024/10/6 updated: 2024/10/6 author: cmdragon excerpt: app:suspense:resolve 是一个强大的钩子,允许开发者在异步数据解析完成后的最后一步执行必要的处理。通过合理使用该钩子,我们可以优化组件的渲染…

多校A层冲刺NOIP2024模拟赛02 csp-s模拟9

多校A层冲刺NOIP2024模拟赛02 四道题因为暑假被拉去当模拟赛 暑假集训CSP提高模拟22 了,遂直接把赛后代码交了上去,然后就被通知换题了。 原 \(100+100+100+20\) 被在 accoders NOI 上被卡成了 \(100+100+90+10\) ,更改 long long 和 int 后达到了 \(100+100+100+30\) 。 \(…

败者树、置换选择排序、最佳归并树

败者树败者树用一个数组即可实现,而且,上图中的那些方块所代表的结点是不存储在败者树中的置换选择排序 置换选择排序的目的是构造出比工作区更长的初始归并段,而更长就意味着初始归并段会更少,可能会减少归并的趟数,进而减少读写磁盘次数来优化排序时间。 置换选择排序的…

Codeforces Rund 977 div2 个人题解(A~E1)

Codeforces Rund 977 div2 个人题解(A,B,C1,C2,E1) Dashboard - Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round) - Codeforces 火车头 #define _CRT_SECURE_NO_WARNINGS 1​#include <algorithm>#include <array>#include <bitset>#inc…

ide启动多个实例

ide启动多个实例 方法一: ide 2022.X及之后 Run=> Edit Configurations=> 选中项目=> “Build and run”栏=> Modify Options=> 选中“Allow multiple instances”然后就可以run多次项目了 但是要主要改端口 方法二: 先把项目打包,然后启动多个terminal,每个…

周鸿祎:用这10条打造你的完美的商业计划书(附详细讲解)

转载:周鸿祎:用这10条打造你的完美的商业计划书(附详细讲解)_产品 (sohu.com) 江湖上流传着一篇“360大佬周鸿祎版10页商业计划书PPT”,高屋建瓴的讲述了BP制作框架,很有价值。诚然,一个形式上外观精美,具有上有吸引力的BP让人赏心悦目,但更重要的还是有实实在在的内容…

DiLiGenT光度立体数据集

本文对DiLiGenT光度立体数据集进行了详细介绍。简介 ”DiLiGenT“ 光度立体数据集,全称为 calibrated Directional Lightings, objects of General reflectance, and ‘ground Truth’ shapes (normals),即使用标定过的定向光源,对一些具有常见反射率特性的物体进行光度立体…

Pool Kings All In One

Pool Kings All In One 泳池之王 Pool Kings - Mountain Paradise / 泳池之王 - 山间天堂 Utah waterfall MountainPool Kings All In One泳池之王demosPool Kings - Mountain Paradise / 泳池之王 - 山间天堂Utah waterfall Mountainhttps://vimeo.com/233842674 https://www.…

CHT

水电费是否收到fwe】今天探索一下CTH的电脑 PEPPA PIG放映室!tm的图怎么死了