md5.c:
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
static void MD5Transform(UINT4 state[4], unsigned char block[64]);
static void Encode(unsigned char *output, UINT4 *input, unsigned int len);
static void Decode(UINT4 *output, unsigned char *input, unsigned int len);
static void MD5_memcpy(POINTER output, POINTER input, unsigned int len);
static void MD5_memset(POINTER output, int value, unsigned int len);
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (MD5_CTX *context,unsigned char *input,unsigned int inputLen)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (unsigned char digest[16], MD5_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (UINT4 state[4], unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (POINTER output, int value, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
md5.h:
//
// Created by J!nl!n on 15/11/10.
//
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
/* MD5 context. */
typedef struct tagMD5_CTX {
UINT4 state[4];
/* state (ABCD) */
UINT4 count[2];
/* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
#ifdef __cplusplus
extern "C" {
#endif
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen);
void MD5Final(unsigned char digest[16], MD5_CTX *context);
#ifdef __cplusplus
}
#endif
my_md5.c:
#include <common.h>
#include <command.h>
#include <malloc.h>
#include "asm/arch/mach/ms_types.h"
#include "asm/arch/mach/platform.h"
#include "asm/arch/mach/io.h"
#include <ubi_uboot.h>
#include <cmd_osd.h>
#include "md5.h"
static int IsFileExist(char* filename)
{
char tmp[64];
char buffer[4];
if(!GetSDIn()) {//sdout
printf("IsFileExist:%s sdcard out!\r\n", filename);
return 0;
}
memset(tmp,0,sizeof(tmp));
snprintf(tmp, sizeof(tmp) - 1,"fatload mmc 0 %X %s 0x%x 0x0", (U32)buffer, filename, 2);
if(run_command(tmp, 0)){
printf("IsFileExist:%s failed!\r\n", filename);
return 0;
}
printf("IsFileExist:%s ok!\r\n", filename);
return 1;
}
int ReadFileFromSDCard(char* fileName, U32 DstAddr, int offset, int iSize)
{
char tmp[64];
memset(tmp,0,sizeof(tmp));
snprintf(tmp, sizeof(tmp) - 1,"fatload mmc 0 0x%X %s 0x%x 0x%x", (U32)DstAddr, fileName, iSize, offset);
if(run_command(tmp, 0)){
printf("ReadFileFromSDCard:%s failed!\r\n", fileName);
return 0;
}
return iSize;
}
static int GetFileSize(char* filename) //需先初始化fat后再调用
{
loff_t lsize;
if(!IsFileExist(filename)) {
return 0;
}
fat_size(filename, &lsize);
return lsize;
}
//MD5校验文件
#define UPD_BIN_INFO_BYTES (70) //附加在最后的MD5等信息字串
#define MAX_TMP_OTA_FILE_SIZE (4<<20)
#define LOAD_FILE_ADDR (0x21000000)
int UBOOT_MD5_SignKeyCheck(char *fileName)
{
int i = 0;
int s32Len = 1;
int s32FileLen = 0;
char* SignKey = NULL;
MD5_CTX ctx;
unsigned char strMD5[72] = {0};
unsigned char Encoder[16] = {0};
unsigned char token[33] = {0};
unsigned char encodeKey[33] = {0};
long long int readSize = 0;
long long int md5FileSize = 0;
long long int updateFileSize = 0;
unsigned char* rbuff = LOAD_FILE_ADDR;
int iPerBytes = 0;
int iCurPos = 0;
printf("UBOOT_MD5_SignKeyCheck:%s\n",fileName);
MD5Init(&ctx);
//读取校验码以及文件大小
s32Len = GetFileSize(fileName);
if(s32Len<UPD_BIN_INFO_BYTES) {
return -1;
}
ReadFileFromSDCard(fileName, strMD5, s32Len-UPD_BIN_INFO_BYTES, UPD_BIN_INFO_BYTES);
printf("strMD5:%s\n",strMD5);
SignKey = strstr(strMD5, "MYMD5=");
if(SignKey == NULL)
{
printf("UBOOT_MD5_SignKeyCheck error No MYMD5\n");
return -2;
}
updateFileSize = s32Len-strlen(SignKey);
sscanf(SignKey," MYMD5=%s FILE_SIZE=%lld", token, &md5FileSize);
printf("UBOOT_MD5_SignKeyCheck SignKey = %s md5FileSize = %lld \n", SignKey, md5FileSize);
iPerBytes = MAX_TMP_OTA_FILE_SIZE;
//光标移回文件头重新开始读取
iCurPos = 0;
while(iCurPos<md5FileSize)
{
memset(rbuff,0,MAX_TMP_OTA_FILE_SIZE);
if( (iCurPos+iPerBytes) >= md5FileSize) //最后一次读剩余字节数不读完整个缓冲区
{
iPerBytes = md5FileSize-iCurPos;
ReadFileFromSDCard(fileName, rbuff, iCurPos, iPerBytes);
MD5Update(&ctx, (unsigned char*)rbuff, iPerBytes);
readSize += iPerBytes;
iCurPos += iPerBytes;
}
else
{
ReadFileFromSDCard(fileName, rbuff, iCurPos, iPerBytes);
MD5Update(&ctx, (unsigned char*)rbuff, iPerBytes);
readSize += iPerBytes;
iCurPos += iPerBytes;
}
}
MD5Final(Encoder, &ctx);
//获得校验码字符串
char tempbuf[3] = {0};
for(i=0;i<16;i++)
{
memset(tempbuf, 0, 3);
sprintf(tempbuf, "%02x", Encoder[i]);
strcat(encodeKey, tempbuf);
printf("%02x", Encoder[i]);
}
if(0 == memcmp(encodeKey, token, 32) && (md5FileSize == readSize))
{
printf("\n MD5 check succeed\n");
return 0;
}
printf("\nmem: MD5 = %s Size = %lld\n", encodeKey, readSize);
printf("\nfile: MD5 = %s Size = %lld\n", token, md5FileSize);
return -3;
}
myuboot.h:
#ifndef __MYUBOOT_H_
#define __MYUBOOT_H_
#include "my.h"
//#define _NOR_FLASH 1 //!!!!!!! 根据实际修改
#define MAX_SUB_PARTS (10)
#if _NOR_FLASH
#define FLASH_MIN_ERASE_SIZE (0x10000)
#else
#define FLASH_MIN_ERASE_SIZE (0x20000)
//注意mtdblock9的大小, 目前是640K, 只能放5个sub分区
#endif
#define _MTD_PART_UI_AUTH_NAME "MTD_PART_UI"
#define _MTD_PART_UI_AUTH_BASE_PART "KEY_CUST"
#define _MTD_PART_UI_AUTH_OFFSET (0)
#define _MTD_PART_FACTORY_PARAM_NAME "MTD_PART_FACTORY"
#define _MTD_PART_FACTORY_PARAM_BASE_PART "KEY_CUST"
#define _MTD_PART_FACTORY_PARAM_OFFSET (_MTD_PART_UI_AUTH_OFFSET+FLASH_MIN_ERASE_SIZE)
#define _MTD_PART_SPEECH_AUTH_NAME "MTD_PART_SPEECH"
#define _MTD_PART_SPEECH_AUTH_BASE_PART "KEY_CUST"
#define _MTD_PART_SPEECH_AUTH_OFFSET (_MTD_PART_FACTORY_PARAM_OFFSET+FLASH_MIN_ERASE_SIZE)
#define _MTD_PART_SETTINGS_NAME "MTD_PART_SETTINGS"
#define _MTD_PART_SETTINGS_BASE_PART "KEY_CUST"
#define _MTD_PART_SETTINGS_OFFSET (_MTD_PART_SPEECH_AUTH_OFFSET+FLASH_MIN_ERASE_SIZE)
#define _MTD_PART_END_NAME "MTD_PART_END"
#define _MTD_PART_END_BASE_PART "END"
#define _MTD_PART_END_OFFSET (0)
typedef enum _UPD_STAT{
UPD_NO_FILE=0, //没有升级文件
UPD_SUCCEED = 1, //升级成功
UPD_MD5_ERR = 2, //MD5校验错误
UPD_OTHER_ERR = 3, //其他错误
}UPD_STAT;
#endif //__UBOOT_H_
在cmd_mstar.c中添加命令函数,在命令函数里面添加校验 逻辑:
int do_sdstar (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#if 1 //uboot升级时校验升级包MD5
if(!IsFileExist(UPD_SKIP_MD5)) {
if(UBOOT_MD5_SignKeyCheck(UpgradeImage)) {
run_command("bootlogo 3 0 0 0", 0);
//SetBackLight(1); //backlight on
g_UpdStatus = UPD_MD5_ERR;//2
//_Error_PwrOff(3, 0, "MD5 mismatch");
return -9;
}
}
#endif
snprintf(tmp, sizeof(tmp) - 1,"setenv updatefail succeed");
run_command(tmp, 0);
script_buf = buffer;
while ((next_line = get_script_next_line(&script_buf)) != NULL)
{
ParseUpdateInfo(next_line);
printf("CMD LINE: %s\n", next_line);
//if(!bFactoryUpd && !bForceUpd) //非工厂模式升级,并且没有强制升级,跳过UBI分区升级
if(bOtaUpd) {
//todo...ota升级跳过IPL,IPL_CUST
}
ret = run_command(next_line, 0);
if(ret) {
if(strstr(next_line, "fatload")) {
run_command("mmc rescan", 0);
printf("retry CMD LINE: %s\n", next_line);
ret = run_command(next_line, 0);
if(ret) {
bUpdateRet = ret;
#if 0
snprintf(tmp, sizeof(tmp) - 1,"setenv updatefail %s", strImgPackTime);
run_command(tmp, 0);
//run_command("save", 0);
#else
run_command("reset", 0);
#endif
}
}
}
//if((!IsFileExist(UPDATE_BIN_FILENAME)) && (!IsFileExist(UPDATE_BIN_FILENAME_1)))
// break;
#if defined(CONFIG_SSTAR_UPGRADE_UI)
cur_cmd++;
memset(tmp,0,sizeof(tmp));
snprintf(tmp, sizeof(tmp) - 1,"dcache on");
run_command(tmp, 0);
memset(tmp,0,sizeof(tmp));
#if defined(CONFIG_SSTAR_UPGRADE_UI_WITH_TXT)
snprintf(tmp, sizeof(tmp) - 1,"bootframebuffer progressbar %d %s", cur_cmd * 100 / total_cmd,next_line);
#else
snprintf(tmp, sizeof(tmp) - 1,"bootframebuffer bar %d", cur_cmd * 100 / total_cmd);
#endif
run_command(tmp, 0);
memset(tmp,0,sizeof(tmp));
snprintf(tmp, sizeof(tmp) - 1,"dcache off");
run_command(tmp, 0);
#endif
}
#if defined(CONFIG_SSTAR_UPGRADE_UI)
memset(tmp,0,sizeof(tmp));
snprintf(tmp, sizeof(tmp) - 1,"dcache on");
run_command(tmp, 0);
memset(tmp,0,sizeof(tmp));
#if defined(CONFIG_SSTAR_UPGRADE_UI_WITH_TXT)
snprintf(tmp, sizeof(tmp) - 1, "bootframebuffer progressbar 100");
#else
snprintf(tmp, sizeof(tmp) - 1, "bootframebuffer bar 100");
#endif
run_command(tmp, 0);
memset(tmp,0,sizeof(tmp));
snprintf(tmp, sizeof(tmp) - 1,"dcache off");
run_command(tmp, 0);
#endif
//lidan@apical
ret = _Uboot_Setings_GetStrVal(COMMON_KEY_SETTINGS_VERSION, tmp, sizeof(tmp)-1);
if(strcmp(tmp, COMMON_VAL_SETTINGS_VERSION)) {
bSettingsValMisMatch = 1;
}
if(!bFactoryUpd) //非工厂模式升级,擦除产测标志位
{
//2021-727,ld@apical 不擦除了,里面可以存PSN和BSN, 需要擦除的时候产测工具通过AT命令擦除
//_Uboot_MtdWrite(_MTD_PART_FACTORY_PARAM_NAME, NULL, 100, 1);
}
if(IsFileExist(ERASE_UI_AUTH))
_Uboot_EraseUiAuth();
if((!bOtaUpd) || bSettingsValMisMatch)
{
_Uboot_EraseSettings();
}
extern void ShowProgressBar(char* strinfo, char dwBarPos);
SetLed(APICAL_GPIO_RED_LED, 0);// red led
SetLed(APICAL_GPIO_BLUE_LED, 0);// blue led
SetLed(APICAL_GPIO_GREEN_LED, 1);// green led
if(bForceUpd)
{
run_command("setenv forceupd 1", 0);
}
if(g_FlashType == 1)//nand
{
if(((!IsFileExist(UPDATE_BIN_FILENAME)) && (!IsFileExist(UPDATE_BIN_FILENAME_1))) || bUpdateRet)
{
snprintf(tmp, sizeof(tmp) - 1,"bootlogo 2 0 0 0"); //升级失败
run_command(tmp, 0);
}
else
{
snprintf(tmp, sizeof(tmp) - 1,"bootlogo 2 0 0 0"); //升级成功
run_command(tmp, 0);
snprintf(tmp, sizeof(tmp) - 1,"setenv PackTime %s", strImgPackTime); //升级成功
run_command(tmp, 0);
run_command("saveenv", 0);
}
run_command(tmp, 0);
mdelay(1500);
}
else
{
if(((!IsFileExist(UPDATE_BIN_FILENAME)) && (!IsFileExist(UPDATE_BIN_FILENAME_1))) || bUpdateRet)
ShowProgressBar("Update failed!", 100);
else
{
snprintf(tmp, sizeof(tmp) - 1,"setenv PackTime %s", strImgPackTime); //升级成功
run_command(tmp, 0);
run_command("saveenv", 0);
ShowProgressBar("Update succeed!", 100);
}
}
//todo.... if factory txt, do not boot, stop here
//*pRebootCfg = 0x12345678;
free(buffer);
printf("************** update %s ************\n", bUpdateRet?"failed":"succeed");
if(IsFileExist("UPDPWROFF.txt"))
{
//UbootPwrOff();
FactoryUbootPwrOff();
while(1)
{
mdelay(200);
//UbootPwrOff();
FactoryUbootPwrOff();
}
}
if(IsFileExist("UPDWAIT.txt"))
{
//ShowProgressBar("Update comple! please pulgout dc to power off!", 300);
while(1)
{
mdelay(200);
if(!GetDc()) {
printf("**** DC out, pwroff *****\n");
UbootPwrOff();
}
if(!GetSDIn()) { //sdout
printf("**** sd out, pwroff *****\n");
UbootPwrOff();
}
}
}
run_command("reset", 0);
return ret;
}
int do_sdstar_apical(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
do_sdstar(cmdtp, flag, argc, argv);
}
U_BOOT_CMD(
sdstar, CONFIG_SYS_MAXARGS, 1, do_sdstar_apical,
"script via sd package",
""
);
alientek_uboot/arch/arm/lib/bootm.c中的boot_prep_linux函数主要用于处理环境变量bootargs,bootargs 保存着传递给 Linux kernel 的参数,在这里添加的主要作用是升级包校验不过的时候向内核层传递参数upload=2,然后再应用层上如果读取到这个参数就删除对应的升级包文件。
void AddToCmdLine(char* pCmdline, char *str)
{
if(pCmdline && str)
{
if(str[0]) {
strcat(pCmdline, " ");
strcat(pCmdline, str);
}
}
}
应用层读取到upload=2就删除升级包:
int ReadFile(const char* szFile, char* pStr, unsigned int size)
{
FILE* pFile = 0;
unsigned char uRet = 0;
int iReadBytes = 0;
do
{
pFile = fopen(szFile, "rb");
if (pFile == NULL)
{
uRet = 1;
break;
}
iReadBytes = fread(pStr, 1, size, pFile);
if (iReadBytes < 0)
{
uRet = 2;
break;
}
}while(0);
if (pFile)
{
fclose(pFile);
pFile = 0;
}
if (uRet)
{
LOGV("ReadFile---%s---failed!uRet=%d (%d bytes)\r\n", szFile, uRet, iReadBytes);
return uRet;
}
else
{
return 0;
}
}
int CheckCmdLime(const char* sig)
{
char *pbuf = new char[MAX_CMD_LINE_SIZE+1];
char *pRse =NULL;
bool bRet = false;
if(pbuf)
{
memset(pbuf, 0, MAX_CMD_LINE_SIZE+1);
ReadFile("/proc/cmdline", pbuf, MAX_CMD_LINE_SIZE);
pbuf[MAX_CMD_LINE_SIZE] = 0;
pRse = strstr(pbuf, sig);
if(pRse)
{
LOGV("get cmdline: %s\n", pbuf);
bRet = true;
}
delete[] pbuf;
}
return bRet;
}
在应用层挂卡成功后调用这段代码就可以实现删除操作:
if(CheckCmdLime("upload=2")) {
sprintf(strBinPath, "rm -f /mnt/mmc/%s.bin &", DEVICE_NAME);
system(strBinPath);
system("rm -f /mnt/mmc/OTAUPD.txt");
}