2025-05-10 21:58:58 +08:00

493 lines
12 KiB
C

/*
* Copyright (c) 2018 Rockchip Electronics Co. Ltd.
* Author: chad.ma <chad.ma@rock-chips.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "update_recv.h"
DWORD m_fwOffset;
FILE* pImgFile;
long long m_fileSize = 0;
bool bCheck = false;
char mnt_point[256];
char* try_mount_point[10] = {
"/udisk/",
"/mnt/udisk/",
"/mnt/usb_storage/",
"/mnt/sdcard/",
"/mnt/external_sd/",
NULL,
};
long long GetFwSize(char* fwFilePath)
{
struct stat statBuf;
char szName[256];
memset(szName, 0, sizeof(szName));
strcpy(szName,fwFilePath);
memset(mnt_point, 0, sizeof(mnt_point));
if (access(szName, F_OK) == 0) {
if (stat(szName, &statBuf) < 0){
printf("%s : stat fail, try \n", szName);
return -1;
}
strcpy(mnt_point, szName);
m_fileSize = statBuf.st_size;
return m_fileSize;
} else {
//try
int i = 0;
while(try_mount_point[i] != NULL) {
memset(szName, 0, sizeof(szName));
strcpy(szName, try_mount_point[i]);
strcat(szName, UPDATE_IMG);
printf("===>>>>We will try: %s \n", szName);
if (access(szName, F_OK) == 0) {
//find valid mount point.
if (stat(szName, &statBuf) < 0){
printf("%s : stat fail, try again\n", szName);
return -1;
}
strcpy(mnt_point, szName);
m_fileSize = statBuf.st_size;
printf("Get Fw total Size = %lld Bytes\n", m_fileSize);
return m_fileSize;
}
i++;
}
printf("*** No find valid mount point for 'update.img' ***\n");
}
return m_fileSize;
}
bool GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)
{
if ( dwOffset<0 || dwSize==0 )
return false;
if ( dwOffset + dwSize > m_fileSize)
return false;
//lseek64(pImgFile,dwOffset,SEEK_SET);
fseek(pImgFile, dwOffset, SEEK_SET);
UINT uiActualRead;
uiActualRead = fread(lpBuffer, 1, dwSize, pImgFile);
//uiActualRead = read(pImgFile, lpBuffer, dwSize);
if (dwSize != uiActualRead)
return false;
return true;
}
DWORD GetFwOffset(FILE* pImageFile)
{
int ret;
long long ulFwSize;
STRUCT_RKIMAGE_HEAD imageHead;
fseeko(pImageFile, 0, SEEK_SET);
ret = fread((PBYTE)(&imageHead),1,sizeof(STRUCT_RKIMAGE_HEAD),pImageFile);
//ret = read(pImageFile, (PBYTE)(&imageHead), sizeof(STRUCT_RKIMAGE_HEAD));
if (ret != sizeof(STRUCT_RKIMAGE_HEAD)){
printf("%s<%d> Read update.img failed!\n", __func__, __LINE__);
fclose(pImageFile);
return -1;
}
if ( imageHead.uiTag!=0x57464B52 ) {
bCheck = false;
return -1;
}
return imageHead.dwFWOffset;
}
static void ShowLog(char* fwImg, bool isCheck)
{
printf("===========================\n");
if (!isCheck)
printf(" update %s start\n", fwImg);
else
printf(" Check %s start\n", fwImg);
}
int WriteFwData(char* imgPath, char* fwName)
{
bool bRet;
long long fwSize = 0;
long long dwFwOffset;
STRUCT_RKIMAGE_HDR rkImageHead;
int idx,iHeadSize;
FILE* pRecvNode = NULL;
long long fileBufferSize;
long long EntryStartOffset;
UINT uiWriteByte = 0;
long long uiEntryOffset = 0;
PBYTE pBuffer = NULL;
UINT uiBufferSize = LBA_TRANSFER_SIZE;
printf("### %s() Enter \n", __func__);
ShowLog(fwName, false);
fwSize = GetFwSize(imgPath);
if (fwSize < 0) {
printf("GetFwSize %s Error\n", imgPath);
return -2;
}
if (mnt_point[0] == 0) {
printf("### Error : Not find update.img ### \n");
return -2;
}
pImgFile = fopen(mnt_point, "rb");
if (pImgFile == NULL)
{
printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
mnt_point, strerror(errno));
return -2;
}
m_fwOffset = GetFwOffset(pImgFile);
if (bCheck == false && m_fwOffset < 0) {
printf("GetFwOffset %s Error\n", imgPath);
return -2;
}
printf("m_fwOffset = 0x%08x \n", m_fwOffset);
dwFwOffset = m_fwOffset;
iHeadSize = sizeof(STRUCT_RKIMAGE_HDR);
bRet = GetData(dwFwOffset, iHeadSize, (PBYTE)&rkImageHead);
if ( !bRet )
{
printf("### GetData error ###\n");
return -2;
}
if (rkImageHead.item_count <= 0)
{
printf("### ERROR:DownloadImage-->No Found item ###\n");
return -2;
}
for (idx = 0; idx < rkImageHead.item_count; idx++) {
if (strcmp(rkImageHead.item[idx].name, fwName) != 0)
continue;
else
break;
}
if (idx == rkImageHead.item_count) {
printf("## Not found %s in update.img ##\n", fwName);
goto ERR;
}
pRecvNode = fopen(DEV_RECOVERY_NODE, "wb");
if (pRecvNode == NULL)
{
printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
DEV_RECOVERY_NODE, strerror(errno));
return -1;
}
//lseek(pRecvNode, 0, SEEK_SET);
fseek(pRecvNode, 0, SEEK_SET);
for (idx = 0; idx < rkImageHead.item_count; idx++ )
{
if (strcmp(rkImageHead.item[idx].name, fwName) != 0)
continue;
if (rkImageHead.item[idx].file[55]=='H') {
fileBufferSize = *((DWORD *)(&rkImageHead.item[idx].file[56]));
fileBufferSize <<= 32;
fileBufferSize += rkImageHead.item[idx].size;
}
else
fileBufferSize = rkImageHead.item[idx].size;
printf("fileBufferSize = 0x%08x \n", fileBufferSize);
if (fileBufferSize > 0) {
DWORD dwFWOffset;
dwFWOffset = m_fwOffset;
if (rkImageHead.item[idx].file[50]=='H') {
EntryStartOffset = *((DWORD *)(rkImageHead.item[idx].file[51]));
EntryStartOffset <<= 32;
EntryStartOffset += rkImageHead.item[idx].offset;
EntryStartOffset += dwFWOffset;
} else {
EntryStartOffset = dwFWOffset;
EntryStartOffset += rkImageHead.item[idx].offset;
}
pBuffer = (PBYTE)malloc(uiBufferSize * sizeof(BYTE));
if (pBuffer == NULL) {
printf("Error, No enough memory!!!\n");
return -1;
}
while ( fileBufferSize > 0 ) {
memset(pBuffer,0,uiBufferSize);
if ( fileBufferSize < uiBufferSize ) {
uiWriteByte = fileBufferSize;
} else {
uiWriteByte = uiBufferSize;
}
bRet = GetData(dwFWOffset + rkImageHead.item[idx].offset + uiEntryOffset,
uiWriteByte,pBuffer);
if ( !bRet ) {
printf("ERROR:RKA_File_Download-->GetFileData failed\n");
goto ERR;
}
size_t sizeWr = fwrite(pBuffer, 1, uiWriteByte, pRecvNode);
//size_t sizeWr = write(recvNode_fd, pBuffer, uiWriteByte);
if (sizeWr != uiWriteByte) {
printf("### Write Error !!!\n");
goto ERR;
}
printf("=");
fileBufferSize -= uiWriteByte;
uiEntryOffset += uiWriteByte;
}
}
printf("\n\n");
printf("================== Update %s Success ==============\n", fwName);
}
if (pRecvNode != NULL) {
fclose(pRecvNode);
pRecvNode = NULL;
}
if (pImgFile != NULL) {
fclose(pImgFile);
pImgFile = NULL;
}
return 0;
ERR:
if (pBuffer) {
free(pBuffer);
pBuffer = NULL;
}
if (pRecvNode != NULL) {
fclose(pRecvNode);
pRecvNode = NULL;
}
if (pImgFile != NULL) {
fclose(pImgFile);
pImgFile = NULL;
}
printf("\n\n");
printf("================== Update %s Fail ==============\n", fwName);
return -1;
}
bool CheckFwData(char* imgPath, char* fwName)
{
bool bRet;
long long dwFwOffset;
STRUCT_RKIMAGE_HDR rkImageHead;
int idx,iHeadSize;
FILE* pRecvNode = NULL;
long long fileBufferSize;
long long EntryStartOffset;
UINT uiReadByte = 0;
long long uiEntryOffset = 0;
PBYTE pBufferFromImg = NULL;
PBYTE pBufferFromFlash = NULL;
UINT uiBufferSize = LBA_TRANSFER_SIZE;
printf("### %s() Enter \n", __func__);
ShowLog(fwName, true);
if (m_fileSize < 0) {
printf("get %s file size Error\n", imgPath);
return false;
}
if (mnt_point[0] == 0) {
printf("### Error : Not find update.img ### \n");
return false;
}
pImgFile = fopen(mnt_point, "rb");
if (pImgFile == NULL)
{
printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
mnt_point, strerror(errno));
return false;
}
if (bCheck == false && m_fwOffset < 0) {
printf("GetFwOffset %s Error\n", imgPath);
return false;
}
printf("m_fwOffset = 0x%08x \n", m_fwOffset);
dwFwOffset = m_fwOffset;
iHeadSize = sizeof(STRUCT_RKIMAGE_HDR);
bRet = GetData(dwFwOffset, iHeadSize, (PBYTE)&rkImageHead);
if ( !bRet )
{
printf("### GetData error ###\n");
return false;
}
pRecvNode = fopen(DEV_RECOVERY_NODE, "rb");
if (pRecvNode == NULL)
{
printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
DEV_RECOVERY_NODE, strerror(errno));
return false;
}
//lseek(pRecvNode, 0, SEEK_SET);
fseek(pRecvNode, 0, SEEK_SET);
for (idx = 0; idx < rkImageHead.item_count; idx++ )
{
if (strcmp(rkImageHead.item[idx].name, fwName) != 0)
continue;
if (rkImageHead.item[idx].file[55]=='H') {
fileBufferSize = *((DWORD *)(&rkImageHead.item[idx].file[56]));
fileBufferSize <<= 32;
fileBufferSize += rkImageHead.item[idx].size;
}
else
fileBufferSize = rkImageHead.item[idx].size;
printf("fileBufferSize = 0x%08x \n", fileBufferSize);
if (fileBufferSize > 0) {
DWORD dwFWOffset;
dwFWOffset = m_fwOffset;
if (rkImageHead.item[idx].file[50]=='H') {
EntryStartOffset = *((DWORD *)(rkImageHead.item[idx].file[51]));
EntryStartOffset <<= 32;
EntryStartOffset += rkImageHead.item[idx].offset;
EntryStartOffset += dwFWOffset;
} else {
EntryStartOffset = dwFWOffset;
EntryStartOffset += rkImageHead.item[idx].offset;
}
pBufferFromImg = (PBYTE)malloc(uiBufferSize * sizeof(BYTE));
if (pBufferFromImg == NULL) {
printf("Error, No enough memory!!!\n");
return false;
}
pBufferFromFlash = (PBYTE)malloc(uiBufferSize * sizeof(BYTE));
if (pBufferFromFlash == NULL) {
printf("Error, No enough memory!!!\n");
return false;
}
while ( fileBufferSize > 0 ) {
memset(pBufferFromImg, 0, uiBufferSize);
memset(pBufferFromFlash, 0, uiBufferSize);
if ( fileBufferSize < uiBufferSize ) {
uiReadByte = fileBufferSize;
} else {
uiReadByte = uiBufferSize;
}
bRet = GetData(dwFWOffset + rkImageHead.item[idx].offset + uiEntryOffset,
uiReadByte,pBufferFromImg);
if ( !bRet ) {
printf("ERROR:RKA_File_Download-->GetFileData failed\n");
goto ERR;
}
size_t sizeRd = fread(pBufferFromFlash, 1, uiReadByte, pRecvNode);
//size_t sizeRd = read(recvNode_fd, pBuffer, uiWriteByte);
if (sizeRd != uiReadByte) {
printf("### Read from flash Error !!!\n");
goto ERR;
}
if (memcmp(pBufferFromImg, pBufferFromFlash, uiReadByte) != 0) {
goto ERR;
}
printf("=");
fileBufferSize -= uiReadByte;
uiEntryOffset += uiReadByte;
}
}
printf("\n\n");
printf("================== Check %s Success ==============\n", fwName);
}
if (pRecvNode != NULL) {
fclose(pRecvNode);
pRecvNode = NULL;
}
if (pImgFile != NULL) {
fclose(pImgFile);
pImgFile = NULL;
}
return true;
ERR:
if (pBufferFromImg) {
free(pBufferFromImg);
pBufferFromImg = NULL;
}
if (pBufferFromFlash) {
free(pBufferFromFlash);
pBufferFromFlash = NULL;
}
if (pRecvNode != NULL) {
fclose(pRecvNode);
pRecvNode = NULL;
}
if (pImgFile != NULL) {
fclose(pImgFile);
pImgFile = NULL;
}
printf("\n\n");
printf("================== Check %s Fail ==================\n", fwName);
return false;
}