| /* |
| * \file sysrecovery.c |
| * \brief |
| * |
| * \version 1.0.0 |
| * \date Friday,14/11/21 |
| * \author Sam.Wu <yihui.wu@amlgic.com> |
| * |
| * Copyright (c) 2014 Amlogic. All Rights Reserved. |
| * |
| */ |
| #include "../v2_burning_i.h" |
| #include "../v2_sdc_burn/optimus_sdc_burn_i.h" |
| #include "../v2_sdc_burn/optimus_led.h" |
| |
| #define CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA 1 |
| |
| static int optimus_sysrec_check_whole_img_before_burn(const char* partName) |
| { |
| //TODO: |
| return 0; |
| } |
| |
| #if CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA |
| //clear data parts then the parts will formatted when firtsboot |
| //As fill half parttition need so much time, I just clear 2M |
| static int optimus_sysrec_clear_usr_data_parts(void) |
| { |
| const char* const _usrDataParts[] = {"data",}; |
| const int dataPartsNum = sizeof(_usrDataParts)/sizeof(const char*); |
| const unsigned BufSz = 1U<<20;//1MB |
| unsigned char* clearBuf= (unsigned char*)OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR; |
| int partIndex = 0; |
| int ret = 0; |
| |
| memset(clearBuf, 0xff, BufSz); |
| for (partIndex = 0; partIndex < dataPartsNum; ++partIndex) |
| { |
| u64 partCap = 0; |
| const char* thePart = _usrDataParts[partIndex]; |
| int rcode = 0; |
| u64 offset = 0; |
| u64 ClearSz = 2U<<20; |
| |
| DWN_MSG("To clear data part[%s]\n", thePart); |
| partCap = store_part_size(thePart); |
| if (rcode) { |
| DWN_ERR("Fail to get partSz for part[%s]\n", thePart); |
| return rcode; |
| } |
| //FIXME: If there is fschk before firstboot, the 2MB to destroy the data if not enough |
| /*ClearSz = partCap>>1;*/ |
| DWN_MSG("partCap 0x%llxMB, ClearSz=%llxMb\n", (partCap>>20), (ClearSz>>20)); |
| |
| for (; offset < ClearSz; offset += BufSz) |
| { |
| rcode = store_write(thePart, offset, BufSz, clearBuf); |
| if (rcode) { |
| DWN_ERR("Failed when clear data part[%s], rcode=%d\n", thePart, rcode); |
| ret += rcode; |
| } |
| } |
| } |
| |
| return ret; |
| } |
| #endif//#if CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA |
| |
| /* |
| *.partName: aml_sysrecovery |
| *.needVerify: 1 then verify partitions that contain verify file; 0 then not to verify for faster burning |
| */ |
| static int optimus_sysrec_burn_package_from_partition(const char* partName, const unsigned needVerifyWhileBurn, |
| const unsigned verifyPackageBeforeBurn) |
| { |
| extern ConfigPara_t g_sdcBurnPara ; |
| ConfigPara_t* pSdcCfgPara = &g_sdcBurnPara; |
| __hdle hUiProgress = NULL; |
| HIMAGE hImg = NULL; |
| int ret = 0; |
| |
| ret = optimus_storage_init(0);//Init all partitions for burning |
| |
| if (verifyPackageBeforeBurn) |
| { |
| ret = optimus_sysrec_check_whole_img_before_burn(partName); |
| if (ret) { |
| DWN_ERR("Failed in crc check the burning package.\n"); |
| return __LINE__; |
| } |
| } |
| |
| hImg = image_open("store", "0", AML_SYS_RECOVERY_PART, ""); |
| if (!hImg) { |
| DWN_ERR("Fail to open image in part %s\n", AML_SYS_RECOVERY_PART); |
| ret = __LINE__; goto _finish; |
| } |
| |
| if (video_res_prepare_for_upgrade(hImg)) { |
| DWN_ERR("Fail when prepare bm res or init video for upgrade\n"); |
| ret = __LINE__; goto _finish; |
| } |
| show_logo_to_report_burning(); |
| |
| hUiProgress = optimus_progress_ui_request_for_sdc_burn(); |
| if (!hUiProgress) { |
| DWN_ERR("request progress handle failed!\n"); |
| ret = __LINE__; goto _finish; |
| } |
| optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STEPS_AFTER_DISK_INIT_OK); |
| |
| int hasBootloader = 0; |
| u64 datapartsSz = optimus_img_decoder_get_data_parts_size(hImg, &hasBootloader); |
| DWN_MSG("datapartsSz=[%8u]MB\n", (unsigned)(datapartsSz >> 20)); |
| ret = optimus_progress_ui_set_smart_mode(hUiProgress, datapartsSz, |
| UPGRADE_STEPS_FOR_BURN_DATA_PARTS_IN_PKG(!pSdcCfgPara->burnEx.bitsMap.mediaPath)); |
| if (ret) { |
| DWN_ERR("Fail to set smart mode\n"); |
| ret = __LINE__; goto _finish; |
| } |
| |
| pSdcCfgPara->burnParts.burn_num = 0; |
| ret = optimus_sdc_burn_partitions(pSdcCfgPara, hImg, hUiProgress, needVerifyWhileBurn); |
| if (ret) { |
| DWN_ERR("Fail when burn partitions\n"); |
| ret = __LINE__; goto _finish; |
| } |
| |
| #if 0 |
| ret = optimus_sdc_burn_dtb_load(hImg); |
| if (ITEM_NOT_EXIST != ret && ret) { |
| DWN_ERR("Fail in load dtb for sdc_burn\n"); |
| ret = __LINE__; goto _finish; |
| } |
| ret = optimus_save_loaded_dtb_to_flash(); |
| if (ret) { |
| DWN_ERR("FAiled in dtb wr\n"); |
| return __LINE__; |
| } |
| #endif |
| |
| optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STPES_AFTER_BURN_DATA_PARTS_OK); |
| |
| #if CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA |
| optimus_sysrec_clear_usr_data_parts(); |
| #endif// #if CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA |
| #if 1 |
| if (hasBootloader) |
| {//burn bootloader |
| ret = optimus_burn_bootlader(hImg); |
| if (ret) { |
| DWN_ERR("Fail in burn bootloader\n"); |
| goto _finish; |
| } |
| ret = optimus_set_burn_complete_flag(); |
| if (ret) { |
| DWN_ERR("Fail in set_burn_complete_flag\n"); |
| ret = __LINE__; goto _finish; |
| } |
| } |
| #endif |
| optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STEPS_AFTER_BURN_BOOTLOADER_OK); |
| |
| _finish: |
| image_close(hImg); |
| optimus_progress_ui_report_upgrade_stat(hUiProgress, !ret); |
| optimus_report_burn_complete_sta(ret, 1/*pSdcCfgPara->custom.rebootAfterBurn*/); |
| optimus_progress_ui_release(hUiProgress); |
| //optimus_storage_exit();//temporary not exit storage driver when failed as may continue burning after burn |
| return ret; |
| } |
| |
| static int do_aml_sysrecovery(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| { |
| int rcode = 0; |
| unsigned needVerify = (1 < argc) ? simple_strtoul(argv[1], NULL, 0) : 0; |
| unsigned verifyPackageBeforeBurn = (2 < argc) ? simple_strtoul(argv[2], NULL, 0) : 0; |
| |
| if (argc < 2 ) { |
| cmd_usage(cmdtp); |
| return __LINE__; |
| } |
| |
| show_logo_to_report_burning();//indicate enter flow of burning! when 'run update' |
| if (optimus_led_open(LED_TYPE_PWM)) { |
| DWN_ERR("Fail to open led for burn\n"); |
| return __LINE__; |
| } |
| optimus_led_show_in_process_of_burning(); |
| |
| optimus_work_mode_set(OPTIMUS_WORK_MODE_SYS_RECOVERY); |
| rcode = optimus_sysrec_burn_package_from_partition(AML_SYS_RECOVERY_PART, needVerify, verifyPackageBeforeBurn); |
| |
| return rcode; |
| } |
| |
| U_BOOT_CMD( |
| aml_sysrecovery, //command name |
| 3, //maxargs |
| 0, //repeatable |
| do_aml_sysrecovery, //command function |
| "Burning with amlogic format package from partition sysrecovery", //description |
| "argv: needVerify [,checkWholeImgBeforeBurn]\n"//usage |
| " --@needVerify: 0 then skip to verify the partition even have verify file." |
| " --@checkWholeImgBeforeBurn: 1 then crc32 check the burn package in partition sysrecovery before actual burn" |
| " eg:'aml_sysrecovery 0': burn from partition aml_sysrecovery without verify" |
| ); |
| |