Files
SDK_GD32W51x/build/tools/remkloader/remkloader.c
2023-06-04 14:36:45 +00:00

237 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#define BOOTSIGN "RK28@Copyright2008Rockchip"
#define BOOTSIGN_SIZE 32
#define CHECK_SIZE 16
#define HEADINFO_SIZE 512
#define BCD2INT(num) (((((num)>>4)&0x0F)*10)+((num)&0x0F))
#define FILE_OPEN_RO "rb"
#define FILE_OPEN_RW "r+b"
#define FILE_OPEN_RW_CREATE "w+b"
#define MAX_LOADER_LEN 1024*1024
typedef struct _rk_time {
unsigned short usYear;
unsigned short usMonth;
unsigned short usDate;
unsigned short usHour;
unsigned short usMinute;
unsigned short usSecond;
}RK_TIME;
typedef struct _RK28BOOT_HEAD{
char szSign[BOOTSIGN_SIZE];
unsigned char bMD5Check[CHECK_SIZE];
RK_TIME tmCreateTime;
unsigned int uiMajorVersion;
unsigned int uiMinorVersion;
unsigned int uiUsbDataOffset;
unsigned int uiUsbDataLen;
unsigned int uiUsbBootOffset;
unsigned int uiUsbBootLen;
unsigned int uiFlashDataOffset;
unsigned int uiFlashDataLen;
unsigned int uiFlashBootOffset;
unsigned int uiFlashBootLen;
unsigned char ucRc4Flag;
unsigned int MergerVersion; // 生成Boot文件所用Merger工具的版本号(高16字节为主版本号、低16字节为副版本号)
}RK28BOOT_HEAD, *PRK28BOOT_HEAD;
#define BOOT_RESERVED_SIZE 57
typedef enum
{
RK27_DEVICE=1,
RK28_DEVICE=2,
RKNANO_DEVICE=4
}ENUM_RKDEVICE_TYPE;
typedef enum
{
ENTRY471=1,
ENTRY472=2,
ENTRYLOADER=4
}ENUM_RKBOOTENTRY;
//#pragma pack(1)
typedef struct
{
unsigned short usYear;
unsigned char ucMonth;
unsigned char ucDay;
unsigned char ucHour;
unsigned char ucMinute;
unsigned char ucSecond;
}__attribute__ ((packed)) STRUCT_RKTIME,*PSTRUCT_RKTIME;
typedef struct
{
unsigned int uiTag;
unsigned short usSize;
unsigned int dwVersion;
unsigned int dwMergeVersion;
STRUCT_RKTIME stReleaseTime;
ENUM_RKDEVICE_TYPE emSupportChip;
unsigned char temp[12];
unsigned char ucLoaderEntryCount;
unsigned int dwLoaderEntryOffset;
unsigned char ucLoaderEntrySize;
unsigned char ucSignFlag;
unsigned char ucRc4Flag;
unsigned char reserved[BOOT_RESERVED_SIZE];
}__attribute__ ((packed)) STRUCT_RKBOOT_HEAD,*PSTRUCT_RKBOOT_HEAD;
typedef struct
{
unsigned char ucSize;
ENUM_RKBOOTENTRY emType;
unsigned char szName[40];
unsigned int dwDataOffset;
unsigned int dwDataSize;
unsigned int dwDataDelay;//以秒为单位
}__attribute__ ((packed)) STRUCT_RKBOOT_ENTRY,*PSTRUCT_RKBOOT_ENTRY;
//#pragma pack()
int make_loader_data(const char* old_loader, char* new_loader, int *new_loader_size)//path, RKIMAGE_HDR *hdr)
{
int i,j;
PSTRUCT_RKBOOT_ENTRY pFlashDataEntry = NULL;
PSTRUCT_RKBOOT_ENTRY pFlashBootEntry = NULL;
STRUCT_RKBOOT_HEAD *boot_hdr = NULL;
RK28BOOT_HEAD *new_hdr = NULL;
boot_hdr = (STRUCT_RKBOOT_HEAD*)old_loader;
// 得到FlashData/FlashBoot数据块的信息
for (i=0;i<boot_hdr->ucLoaderEntryCount;i++)
{
PSTRUCT_RKBOOT_ENTRY pEntry;
pEntry = (PSTRUCT_RKBOOT_ENTRY)(old_loader+boot_hdr->dwLoaderEntryOffset+(boot_hdr->ucLoaderEntrySize*i));
char name[10] = "";
for(j=0; j<20 && pEntry->szName[j]; j+=2)
name[j/2] = pEntry->szName[j];
if( !strcmp( name, "FlashData" ) )
pFlashDataEntry = pEntry;
else if( !strcmp( name, "FlashBoot" ) )
pFlashBootEntry = pEntry;
}
if(pFlashDataEntry == NULL || pFlashBootEntry == NULL)
return -1;
// 构造新的Loader数据以传给Loader进行本地升级
new_hdr = (RK28BOOT_HEAD*)new_loader;
memset(new_hdr, 0, HEADINFO_SIZE);
strcpy(new_hdr->szSign, BOOTSIGN);
new_hdr->tmCreateTime.usYear = boot_hdr->stReleaseTime.usYear;
new_hdr->tmCreateTime.usMonth= boot_hdr->stReleaseTime.ucMonth;
new_hdr->tmCreateTime.usDate= boot_hdr->stReleaseTime.ucDay;
new_hdr->tmCreateTime.usHour = boot_hdr->stReleaseTime.ucHour;
new_hdr->tmCreateTime.usMinute = boot_hdr->stReleaseTime.ucMinute;
new_hdr->tmCreateTime.usSecond = boot_hdr->stReleaseTime.ucSecond;
new_hdr->uiMajorVersion = (boot_hdr->dwVersion&0x0000FF00)>>8;
new_hdr->uiMajorVersion = BCD2INT(new_hdr->uiMajorVersion);
new_hdr->uiMinorVersion = boot_hdr->dwVersion&0x000000FF;
new_hdr->uiMinorVersion = BCD2INT(new_hdr->uiMinorVersion);
new_hdr->uiFlashDataOffset = HEADINFO_SIZE;
new_hdr->uiFlashDataLen = pFlashDataEntry->dwDataSize;
new_hdr->uiFlashBootOffset = new_hdr->uiFlashDataOffset+new_hdr->uiFlashDataLen;
new_hdr->uiFlashBootLen = pFlashBootEntry->dwDataSize;
new_hdr->ucRc4Flag = boot_hdr->ucRc4Flag;
memcpy(new_loader+new_hdr->uiFlashDataOffset, old_loader+pFlashDataEntry->dwDataOffset, pFlashDataEntry->dwDataSize);
memcpy(new_loader+new_hdr->uiFlashBootOffset, old_loader+pFlashBootEntry->dwDataOffset, pFlashBootEntry->dwDataSize);
*new_loader_size = new_hdr->uiFlashBootOffset+new_hdr->uiFlashBootLen;
// dump_data(new_loader, HEADINFO_SIZE);
return 0;
}
int main(int argc, char **argv)
{
char* oldloaderfilename = argv[1];
char* newloaderfilename = argv[2];;
size_t oldloaderfilesize,newloaderfilesize;
FILE *fp;
struct stat buf;
char oldloaderbuf[MAX_LOADER_LEN] = "";
char newloaderbuf[MAX_LOADER_LEN] = "";
// oldloaderfilesize = atoi(argv[2]);
stat(oldloaderfilename, &buf);
oldloaderfilesize = buf.st_size;
printf("oldloaderfilename=%s,oldloaderfilesize=%d,newloaderfilename=%s\n",oldloaderfilename,oldloaderfilesize,newloaderfilename);
fp = fopen(oldloaderfilename, FILE_OPEN_RO);
if(!fp)
{
printf("Can not open file %s !\n",oldloaderfilename);
return -1;
}
if( fread(oldloaderbuf,1,oldloaderfilesize,fp)== oldloaderfilesize)
{
make_loader_data(oldloaderbuf, newloaderbuf, &newloaderfilesize);
}
else
{
printf("read old loader file fail!\n");
}
fclose(fp);
fp = fopen(newloaderfilename, FILE_OPEN_RW_CREATE);
if(fwrite(newloaderbuf,1,newloaderfilesize,fp)== newloaderfilesize)
{
printf("write new loader file success,size=%d \n",newloaderfilesize);
}
else
{
printf("write new loader file fail!\n");
}
fclose(fp);
return 0;
}