#include #include #include #include #include "cpu.h" #include "qspi.h" #include "reg.h" #include "system.h" //#include "uart.h" #include "ptable.h" #include "loadtable.h" #include "sdio.h" #include "pmic.h" #include "ff.h" #include "version_block.h" #include "bspatch.h" #include "fip.h" #include "LzmaDec.h" #include "FreqChange.h" #include "fbf_parse.h" #include "ota.h" #include "tinyalloc.h" #include "asr_property.h" #include "secboot.h" #include "updater_table.h" #ifdef BOOT33_FOTA_SUPPORT #define QUEC_SUPPORT_FULL_FOTA_NAND 1 extern void TransferControl(unsigned int); extern int crane_qspi_read(unsigned int addr, unsigned int buf_addr, unsigned int size); extern int crane_qspi_write(unsigned int addr, unsigned int buf_addr,unsigned int size); extern int crane_qspi_erase(unsigned int addr, unsigned int size); extern int malloc_init(unsigned int ta_base, unsigned int length); extern unsigned int get_fota_param_end_addr(void); extern unsigned int get_fota_param_start_addr(void); extern unsigned int get_ddr_ro_exec_length(void); extern unsigned int get_ddr_ro_exec_addr(void); extern unsigned long mini_system_enable; unsigned int get_ps_ncah_address(void) { char region_compress_mark[8]; unsigned schedule_count = 0; rw_region_item region_info; char * rw_cpz_struct_addr=(char*)get_rw_cpz_struct_addr(); //load region compressed struct memcpy(region_compress_mark, rw_cpz_struct_addr, sizeof(region_compress_mark)); if(!strncmp(region_compress_mark, RW_REGION_MARK_PRE_STRING ,strlen(RW_REGION_MARK_PRE_STRING)-1)){ while(1){ //read NEXT region cpz info struct memcpy(®ion_info ,(void*)(rw_cpz_struct_addr + (sizeof(rw_region_item)*schedule_count++)) ,sizeof(rw_region_item)); //dump region info //uart_printf("[CP ] decompress [%8s] from [%.08x] to [%.08x]\r\n", // region_info.RW_REGION_NAME, // region_info.RW_REGION_COMPRESSED_ADDR, // region_info.RW_REGION_EXEC_ADDR // ); if(!strncmp(region_info.RW_REGION_NAME,"PS_NCAH",7)){ return region_info.RW_REGION_EXEC_ADDR; } } } else { uart_printf("[CP ] Region CPZ struct not detected from loadtable\r\n"); } return 0; } static void fota_uudelay(int us) { volatile uint32_t i; for(i=0; i10){ uart_printf("OTA_Check_FotaImage filed,Wait...\n\r"); while(1){ fota_mdelay(10*1000); } } uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec ...\n\r",(i+1)*10); fota_mdelay((i+1)*10*1000); uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec end\n\r",(i+1)*10); i++; goto start; } uart_printf("OTA_Update_FotaParam end\n\r"); return Retval; } static UINT32 OTA_Update_FotaImage(UINT32 buf, UINT32 size, UINT32 flash_Addr) { UINT32 Retval = 1; char *temp=NULL; UINT32 index=0; UINT32 tempsize = size; int i=0; uart_printf("OTA_Update_FotaImage: flash_Addr[0x%08x], size: 0x%08x\n\r", flash_Addr, size); start: temp =(char *) tiny_malloc(FLASH_4K_SIZE); while(size > FLASH_4K_SIZE){ memcpy(temp,(char *)(buf+index),FLASH_4K_SIZE); Retval=crane_qspi_erase(flash_Addr + index, FLASH_4K_SIZE); if (Retval != 0) goto error; if(index==0){ #if 0 uart_printf("+++++++++++++++++++++++++++++OTA_Update_FotaImage,delay for poweroff test++++++++++++++\n\r"); fota_delay(); uart_printf("-----------------------------OTA_Update_FotaImage,delay end----------------------------\n\r"); #endif } if(index%FLASH_1M_SIZE==0){ uart_printf("\r\n"); } if(index%CRANE_NOR_BLOCKSIZE==0){ uart_printf("..."); } Retval = crane_qspi_write(flash_Addr + index, (UINT32)temp, FLASH_4K_SIZE); if (Retval != 0) goto error; index += FLASH_4K_SIZE; size -= FLASH_4K_SIZE; } if(size>0){ memset(temp,0,FLASH_4K_SIZE); memcpy(temp,(char *)(buf+index),size); Retval=crane_qspi_erase(flash_Addr + index, FLASH_4K_SIZE); if (Retval != 0) goto error; Retval = crane_qspi_write(flash_Addr + index, (UINT32)temp, FLASH_4K_SIZE); if (Retval != 0) goto error; index += size; size -= size; } Retval = 0; error: if(temp) tiny_free(temp); Retval=OTA_Check_FotaImage(buf,tempsize,flash_Addr); if(NoError!=Retval ){ if(i>10){ uart_printf("OTA_Check_FotaImage filed,Wait...\n\r"); while(1){ fota_mdelay(10*1000); } } uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec ...\n\r",(i+1)*10); fota_mdelay((i+1)*10*1000); uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec end\n\r",(i+1)*10); i++; goto start; } uart_printf("OTA_Update_FotaImage end\n\r"); return Retval; } static UINT32 System_ota_updater(struct fota_firmwar_flag* pFOTA_T,struct fota_param *param,unsigned long FotaParamStartAddress) { UINT32 Retval = GeneralError; UINT32 LoadAddr = 0; MasterBlockHeader *pMasterHeader = NULL; PDeviceHeader_11 pDevHeader_11=NULL; PImageStruct_11 pImage_11 = NULL; UINT32 temp_p = NULL; UINT32 imageChecksum = 0; UINT32 imagenum; UINT32 ImageAddr; UINT32 updaterSize=0,updateImageSize=0; _ptentry * fota_pkg=ptable_find_entry("fota_pkg"); if(fota_pkg==NULL){ uart_printf("[OTA] not found fota_pkg\r\n"); return NotFoundError; } if (pFOTA_T->header != FOTA_HEADER_MAGIC) { uart_printf("[OTA] FBF Flag mismatch,Header[%.08x]\r\n",pFOTA_T->header); return NotFoundError; } if (pFOTA_T->upgrade_flag != 1) { uart_printf("[OTA] No need to upgrade[%d]\r\n",pFOTA_T->upgrade_flag); return NotFoundError; } if(pFOTA_T->upgrade_method != 1) { uart_printf("[OTA] Not ota upgrader\r\n"); return NotOtaUpdaterError; } #if QUEC_SUPPORT_FULL_FOTA_NAND if(pFOTA_T->fbf_file_size > 0x32000)/*fbf bigger then 200k exit*/ { uart_printf("[OTA] FBF greater than 200k,is not updater\r\n"); return NotFoundError; } #endif LoadAddr = (UINT32)tiny_malloc(pFOTA_T->fbf_file_size); if(LoadAddr == 0){ uart_printf("[OTA] tiny_malloc error\n\r"); return InvalidSizeError; } //uart_printf("LoadAddr: 0x%08x\n\r", LoadAddr); memset((void *)LoadAddr,0,pFOTA_T->fbf_file_size); //fota_dump_buffer("MasterBlockHeader",(unsigned char *)pFOTA_T->fbf_flash_address+QSPI_FLASH_BASE,0,sizeof(MasterBlockHeader)); memcpy((void *)LoadAddr,(void*)(pFOTA_T->fbf_flash_address+QSPI_FLASH_BASE),pFOTA_T->fbf_file_size); pMasterHeader = (MasterBlockHeader *)LoadAddr; if (pMasterHeader->Format_Version != 11){ Retval = FBF_VersionNotMatch; goto error; } if (pMasterHeader->nOfDevices != 1){ Retval = FBF_DeviceMoreThanOne; goto error; } temp_p = pMasterHeader->deviceHeaderOffset[0] + LoadAddr; pDevHeader_11 = (PDeviceHeader_11)temp_p; for ( imagenum = pDevHeader_11->nOfImages; imagenum > 0; imagenum -- ) { temp_p = (UINT32)&pDevHeader_11->imageStruct_11[imagenum - 1]; pImage_11 = (PImageStruct_11)temp_p; updaterSize = get_updater_copy_size(); updateImageSize = pImage_11->length; uart_printf("[OTA] Flash_Start_Address: 0x%08x length: 0x%08x\n\r", pImage_11->Flash_Start_Address,updateImageSize); uart_printf("[OTA] get_updater_start_addr: 0x%08x get_updater_copy_size: 0x%08x\n\r", get_updater_start_addr(),updaterSize); if(updateImageSize & (FLASH_4K_SIZE-1)){ updateImageSize += (FLASH_4K_SIZE - updateImageSize & (FLASH_4K_SIZE-1)); } if(get_updater_start_addr()!=(pImage_11->Flash_Start_Address+QSPI_FLASH_BASE) || updaterSize < updateImageSize) { Retval = NotOtaUpdaterError; goto error; } uart_printf("[OTA] boot ota updater, nOfImages: %d\n\r",pDevHeader_11->nOfImages); ImageAddr = LoadAddr+((pImage_11->First_Sector+7)<length,0); if (imageChecksum != pImage_11->ChecksumFormatVersion2){ Retval = CRCFailedError; uart_printf("[OTA]fbf file CORRUPT,checksum failed\n\r"); goto error; } if(pImage_11->ChecksumFormatVersion2==0){ continue; } uart_printf("[OTA] Flash_Start_Address: 0x%08X, EraseLen: 0x%08X, length=0x%08X\n\r", pImage_11->Flash_Start_Address,pImage_11->Flash_erase_size,pImage_11->length); Retval=OTA_Update_FotaImage( ImageAddr, pImage_11->length, pImage_11->Flash_Start_Address); if (Retval != NoError ) goto error; } tiny_free((void*)LoadAddr); LoadAddr=0; memset(param->fotaFlag,0,ASR_FOTA_FLAG_LEN_MAX); param->mini_sys_enable = 0; OTA_Update_FotaParam((UINT32)param, sizeof(struct fota_param),get_fota_param_start_addr()-QSPI_FLASH_BASE); uart_printf("[OTA] Clear upgrade flag OK\r\n"); pFOTA_T->header = 0; pFOTA_T->upgrade_flag = 0; pFOTA_T->upgrade_method = 0; pFOTA_T->checksum = 0; Retval = OTA_Update_FotaParam((UINT32)pFOTA_T, sizeof(struct fota_firmwar_flag),FotaParamStartAddress); if (Retval != NoError) return Retval; Retval = OTA_Update_FotaParam((UINT32)pFOTA_T, sizeof(struct fota_firmwar_flag),FotaParamStartAddress + FLASH_4K_SIZE); if (Retval != NoError) return Retval; uart_printf("[OTA] Clear fota param OK\r\n"); return NoError; error: //free buffers uart_printf("[OTA]ota updater,Retval=%x\n\r", Retval); if(LoadAddr) tiny_free((void*)LoadAddr); return Retval; } #endif #endif #define UpdaterExecAddress 0x7E040000//bind on updater build sct loader config #define UpdaterVersionIndex 0x00800//bind on updater build sct loader config UpdaterHeaderInfo updater_version_vb={0}; extern _ptentry *updater_Entry; void get_updater_vb(void) { #ifdef SUPPORT_EXTERNAL_NORFLASH _ptentry *fipEntry = ptable_find_entry("updater"); #endif #ifdef BOOT33_SECBOOT_SUPPORT #ifdef BOOT33_SECBOOT_V2 if(secboot_is_fuse_enabled()==1){ #endif fip_image_t fip_item; //[sec.0]secboot init from updater partition // which is updater.bin with a secboot ToC struct with only one FIP header // for updater.bin // // |----------------| // | FIP Header | // |----------------| // | Updater.bin | // |----------------| #ifdef SUPPORT_EXTERNAL_NORFLASH unsigned char * updater_buf = NULL; if(fipEntry->vstart >= 0x90000000){ //����updater������flash updater_buf = malloc(fipEntry->size); memset(updater_buf, 0, fipEntry->size); crane_ext_spi_read(fipEntry->start, (unsigned int)updater_buf, fipEntry->vsize); fip_open((void*)updater_buf); }else #endif { //updater������flash secboot_init("updater"); } //[sec.1]do updater verify //Timer0_enable(TRUE); //secboot_item_check(ITEM_UPDATER); //Timer0_enable(FALSE); //[sec.2]get info from fip of updater.bin secboot_item_get_img_addr_size(ITEM_UPDATER,(fip_image_handle)&fip_item); //[sec.3]for debug to dump header of real updater.bin //display_binary((void *)(fip_item.start+fip_item.offset),256); //[sec.4]load updater_a or updater_b to psram memcpy(&updater_version_vb, (void *)(fip_item.start+fip_item.offset), sizeof(UpdaterHeaderInfo)); //memcpy( (void *)UpdaterExecAddress, // (void *)(fip_item.start+fip_item.offset), // fip_item.size // ); #ifdef BOOT33_SECBOOT_V2 secboot_deinit(); } else{ #ifdef SUPPORT_EXTERNAL_NORFLASH if(fipEntry->vstart >= 0x90000000){ //����updater������flash crane_ext_spi_read(fipEntry->start, (unsigned int)&updater_version_vb, sizeof(UpdaterHeaderInfo)); }else #endif memcpy(&updater_version_vb,get_updater_start_addr(),sizeof(UpdaterHeaderInfo)); } #endif #else #ifdef SUPPORT_EXTERNAL_NORFLASH if(fipEntry->vstart >= 0x90000000){ //����updater������flash crane_ext_spi_read(fipEntry->start, (unsigned int)&updater_version_vb, sizeof(UpdaterHeaderInfo)); }else #endif memcpy(&updater_version_vb,get_updater_start_addr(),sizeof(UpdaterHeaderInfo)); #endif asr_property_set("updater.version",updater_version_vb.version_union.version_info_block.string); asr_property_set("updater.solution",updater_version_vb.fota_solution_union.fota_solution_block.string); CP_LOGD("[OTA] get updater version %s !\r\n",updater_version_vb.version_union.version_info_block.string); CP_LOGD("[OTA] get updater solution %s !\r\n",updater_version_vb.fota_solution_union.fota_solution_block.string); } UINT32 UncompressUpdater(struct fota_firmwar_flag *fotaPara,unsigned char * address) { UINT32 res = NoError; int outLen = -1; unsigned int inLen = fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_size; unsigned int offset = fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_offset; unsigned char * inAddr = NULL,*dfota_buf=NULL; if(inLen==0){ return NotFoundError; } CP_LOGD("[OTA] updater_addr [0x%.08x]\r\n", fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_addr); if(fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_addr){ inAddr = fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_addr; inAddr += QSPI_FLASH_BASE; }else{ CP_LOGD("[OTA] first_flash_addr[0x%.08x], first_file_size[0x%.08x]\r\n", fotaPara->ota_header.mini_ota_head.first_flash_addr,fotaPara->ota_header.mini_ota_head.first_file_size); CP_LOGD("[OTA] second_flash_address[0x%.08x], second_file_size[0x%.08x]\r\n", fotaPara->ota_header.mini_ota_head.second_flash_address,fotaPara->ota_header.mini_ota_head.second_file_size); dfota_buf = (unsigned char *)tiny_malloc(fotaPara->ota_header.mini_ota_head.first_file_size + fotaPara->ota_header.mini_ota_head.second_file_size); crane_qspi_read(fotaPara->ota_header.mini_ota_head.first_flash_addr - QSPI_FLASH_BASE, dfota_buf, fotaPara->ota_header.mini_ota_head.first_file_size); if(fotaPara->ota_header.mini_ota_head.second_flash_address && fotaPara->ota_header.mini_ota_head.second_file_size){ crane_qspi_read(fotaPara->ota_header.mini_ota_head.second_flash_address - QSPI_FLASH_BASE, dfota_buf + fotaPara->ota_header.mini_ota_head.first_file_size, fotaPara->ota_header.mini_ota_head.second_file_size); } inAddr = dfota_buf + offset; } if(!LzmaUncompress((unsigned char *)address,(size_t *)&outLen, (const unsigned char *)inAddr, (size_t *)&inLen)) { CP_LOGD("[OTA] released updater size [0x%.08x] inLen[0x%.08x]\r\n", outLen,inLen); memcpy(&updater_version_vb,address,sizeof(UpdaterHeaderInfo)); if(updater_version_vb.loadtable_union.loadtable_block.magic != UPDATER_VALID_MAGIC){ res = UpdaterMagicError; }else{ res=check_updater_ram(address,outLen); if(res){ res = CheckUpdaterError; } } }else{ res = UnpressedUpdaterError; } return res; } void ota_entry(void) { volatile unsigned long FotaParamStartAddress; volatile unsigned long FotaParamEndAddress; struct fota_param param; unsigned long entry_mini_system_only=0; struct fota_firmwar_flag *fotaPara_1=NULL; struct fota_firmwar_flag *fotaPara_2=NULL; struct fota_firmwar_flag *fotaPara=NULL; UINT32 Retval = NoError; UpdaterHeaderInfo updater_version; #ifdef SUPPORT_EXTERNAL_NORFLASH _ptentry *fipEntry = ptable_find_entry("updater"); #endif //detect whether fota partition supported FotaParamStartAddress = get_fota_param_start_addr(); FotaParamEndAddress = get_fota_param_end_addr(); if(FotaParamStartAddress == FotaParamEndAddress){ CP_LOGE("[OTA] FotaParamStartAddress == FotaParamEndAddress , FOTA not supported\r\n"); return; } #if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM)) #if (!defined(CRANEM_SINGLE_SIM)) if(updater_Entry){ get_updater_vb(); asr_property_dump(); } #endif #endif //check OTA flag or memcpy(¶m,(void *)FotaParamStartAddress,sizeof(struct fota_param)); //if(!strncmp(fota_flag,"ASROTA",6) || Keypad_OTA_Flag_Check_B()){ if(!strncmp((char *)param.fotaFlag,"ASROTA",6) ){ UINT32 stack=0x7e200000; //The bspatch/lzma lib needs malloc/free APIs UINT32 poolLen = 0x00600000; malloc_init(stack, poolLen); #if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM)) #if (!defined(CRANEM_SINGLE_SIM)) if(updater_Entry){ #ifdef SUPPORT_EXTERNAL_NORFLASH if(get_updater_start_addr() >= 0x90000000){ crane_ext_spi_read(get_updater_start_addr()-0x90000000, (unsigned int)&updater_version, sizeof(UpdaterHeaderInfo)); }else #endif memcpy(&updater_version,get_updater_start_addr(),sizeof(UpdaterHeaderInfo)); CP_LOGD("[OTA] get updater version %s !\r\n",updater_version.version_union.version_info_block.string); } #endif #endif fotaPara_1=(struct fota_firmwar_flag*)tiny_malloc(sizeof(struct fota_firmwar_flag)); fotaPara_2=(struct fota_firmwar_flag*)tiny_malloc(sizeof(struct fota_firmwar_flag)); memcpy(fotaPara_1,(void *)(FotaParamStartAddress+FLASH_4K_SIZE),sizeof(struct fota_firmwar_flag)); memcpy(fotaPara_2,(void *)(FotaParamStartAddress+2*FLASH_4K_SIZE),sizeof(struct fota_firmwar_flag)); if(fotaPara_1->checksum!=CalcImageChecksum((UINT32*)fotaPara_1,sizeof(struct fota_firmwar_flag)-sizeof(unsigned int),0) || fotaPara_1->header != FOTA_HEADER_MAGIC){ if(fotaPara_2->checksum!=CalcImageChecksum((UINT32*)fotaPara_2,sizeof(struct fota_firmwar_flag)-sizeof(unsigned int),0) || fotaPara_2->header != FOTA_HEADER_MAGIC){ CP_LOGD("[OTA] fotaPara error!!!\r\n"); goto done; }else{ CP_LOGD("[OTA]using fotaPara_2,not copy temp flash\r\n"); fotaPara = fotaPara_2; } }else{ if(fotaPara_2->checksum!=CalcImageChecksum((UINT32*)fotaPara_2,sizeof(struct fota_firmwar_flag)-sizeof(unsigned int),0) || fotaPara_2->header != FOTA_HEADER_MAGIC){ fotaPara = fotaPara_1; CP_LOGD("[OTA]using fotaPara_1,need copy temp flash\r\n"); }else{ if(fotaPara_1->index > fotaPara_2->index){ fotaPara = fotaPara_1; CP_LOGD("[OTA]using fotaPara_1,need copy temp flash\r\n"); }else{ fotaPara = fotaPara_2; CP_LOGD("[OTA]using fotaPara_2,not copy temp flash,checksum[%08x]\r\n",fotaPara_2->checksum); } } } if(param.mini_sys_enable==1){ mini_system_enable=1; if(fotaPara->ota_header.mini_ota_head.mini_dfota_status==MINI_SYS_DFOTA_START){ CP_LOGD("[OTA]MINI_SYS_DFOTA_START\r\n"); entry_mini_system_only = 1; }else if(fotaPara->ota_header.mini_ota_head.mini_dfota_status>=MINI_SYS_DFOTA_DONE){ entry_mini_system_only = 1; CP_LOGD("[OTA]MINI_SYS_DFOTA_DONE\r\n"); } if(entry_mini_system_only==1){ asr_property_set("mini.sys.enable","1"); tiny_free(fotaPara_1); tiny_free(fotaPara_2); uart_printf("[OTA]ENTRY MINI SYSTEM ONLY\r\n"); return; } #if defined(BOOT33_FOTA_NO_UPDATER) if(!updater_Entry){ Retval=UncompressUpdater(fotaPara,UpdaterExecAddress); CP_LOGD("[OTA]UncompressUpdater[%d] %s !!!\r\n",Retval,Retval?"error":"success"); if(Retval != NoError){ CP_LOGE("[OTA] no updater paritition,parse updater failed[%02x]!!!\r\n",Retval); tiny_free(fotaPara_1); tiny_free(fotaPara_2); return; } } #endif tiny_free(fotaPara_1); tiny_free(fotaPara_2); } #if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM)) #if (!defined(CRANEM_SINGLE_SIM)) else{ Retval=System_ota_updater(fotaPara,¶m,FotaParamStartAddress+FLASH_4K_SIZE-QSPI_FLASH_BASE); if(Retval==0){ CP_LOGD("[OTA]System_ota_updater success!\r\n"); #ifdef SUPPORT_EXTERNAL_NORFLASH if(get_updater_start_addr() >= 0x90000000){ crane_ext_spi_read(get_updater_start_addr()-0x90000000, (unsigned int)&updater_version, sizeof(UpdaterHeaderInfo)); }else #endif memcpy(&updater_version,get_updater_start_addr(),sizeof(UpdaterHeaderInfo)); CP_LOGD("[OTA] get new updater version %s !\r\n",updater_version.version_union.version_info_block.string); tiny_free(fotaPara_1); tiny_free(fotaPara_2); return; } tiny_free(fotaPara_1); tiny_free(fotaPara_2); } #endif #endif done: #if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM)) #if (!defined(CRANEM_SINGLE_SIM)) #ifdef ADD_VIBRATOR_IN_CODE //[0] Before jump to updater, disable vibrator NingboVibratorDisable(); #endif //[1] TODO:detect ADUPS flags CP_LOGD("[OTA] ASROTA prefix detected or Keypad Flag detect!\r\n"); if(!updater_Entry){ if(Retval != NoError){ CP_LOGE("[OTA] no updater paritition,parse updater failed[%02x]!!!\r\n",Retval); return; } goto jump; } #ifdef BOOT33_SECBOOT_SUPPORT #ifdef BOOT33_SECBOOT_V2 if(secboot_is_fuse_enabled()==1){ #endif fip_image_t fip_item; //[sec.0]secboot init from updater partition // which is updater.bin with a secboot ToC struct with only one FIP header // for updater.bin // // |----------------| // | FIP Header | // |----------------| // | Updater.bin | // |----------------| #ifdef SUPPORT_EXTERNAL_NORFLASH unsigned char * updater_buf = NULL; if(fipEntry->vstart >= 0x90000000){ //����updater������flash updater_buf = malloc(fipEntry->size); memset(updater_buf, 0, fipEntry->size); crane_ext_spi_read(fipEntry->start, (unsigned int)updater_buf, fipEntry->vsize); fip_open((void*)updater_buf); }else #endif { //updater������flash secboot_init("updater"); } //[sec.1]do updater verify Timer0_enable(TRUE); secboot_item_check(ITEM_UPDATER); Timer0_enable(FALSE); //[sec.2]get info from fip of updater.bin secboot_item_get_img_addr_size(ITEM_UPDATER,(fip_image_handle)&fip_item); //[sec.3]for debug to dump header of real updater.bin //display_binary((void *)(fip_item.start+fip_item.offset),256); //[sec.4]load updater_a or updater_b to psram memcpy( (void *)UpdaterExecAddress, (void *)(fip_item.start+fip_item.offset), fip_item.size ); #ifdef BOOT33_SECBOOT_V2 }else{ //[2] TODO:load updater_a or updater_b to psram #ifdef SUPPORT_EXTERNAL_NORFLASH if(fipEntry->vstart >= 0x90000000){ //����updater������flash crane_ext_spi_read(fipEntry->start, (unsigned int)UpdaterExecAddress, get_updater_copy_size()); }else #endif { memcpy( (void *)UpdaterExecAddress, (void *)get_updater_start_addr(), get_updater_copy_size()); } } #endif #else //[2] TODO:load updater_a or updater_b to psram #ifdef SUPPORT_EXTERNAL_NORFLASH if(fipEntry->vstart >= 0x90000000){ //����updater������flash crane_ext_spi_read(fipEntry->start, (unsigned int)UpdaterExecAddress, get_updater_copy_size()); }else #endif { memcpy( (void *)UpdaterExecAddress, (void *)get_updater_start_addr(), get_updater_copy_size()); } #endif #endif #endif jump: //[3] jump to execute updater CP_LOGD("\r\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); CP_LOGD("\r\n >> BOOTLOADER DONE JUMP TO UPDATER"); CP_LOGD("\r\n >> PC : 0x%x",UpdaterExecAddress); CP_LOGD("\r\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n"); TransferControl(UpdaterExecAddress); }else{ CP_LOGD("[OTA] NO FOTA FLAG DETECTED \r\n"); } } #endif