【uboot学习】uboot添加升级包MD5校验逻辑

文章提供了MD5(Message-DigestAlgorithm5)加密算法的源代码,这是由RSADataSecurity开发的一种广泛用于安全认证的哈希函数。MD5算法主要用于生成数据的数字指纹,确保信息在传输过程中的完整性。代码中包括了MD5的初始化、更新、最终化等关键步骤,以及对输入数据进行编码和解码的辅助函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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");
		}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值