Add ota_cmd, ota_setup command in uboot. Restore private partition. Add ota_setup command to uboot bootcmd

This commit is contained in:
HuangXin 2018-08-27 20:09:13 +08:00
parent ad4d7723a0
commit f02065eec5
4 changed files with 571 additions and 326 deletions

View File

@ -14,7 +14,7 @@
#define MBR_PAGE_SIZE (512)
#define MD5_CHKSUM_LEN (16)
#define OTA_PARAMS_TAG ("OTAPARAM")
#define OTA_PARAMS_TAG ("OTA163")
#define MD5_STR_LEN (32 + 4)
#define OTA_PARTITION_DEV ("sunxi_flash")
@ -24,10 +24,49 @@
#define READ_BOOT_ADDR (READ_OTA_PARAMS_ADDR + (1024 * 1024))
#define READ_ROOTFS_ADDR (READ_BOOT_ADDR + (1024 * 1024 * 4))
#define GET_STA_CNT(s) (s & 0xFF)
#define SET_STA_CNT(s, v) (s = (s & 0xFFFFFF00) | ((v) & 0xFF))
#define GET_STA_CMD(s) ((s >> 8) & 0xFF)
#define SET_STA_CMD(s, v) (s = (s & 0xFFFF00FF) | (((v) & 0xFF) << 8))
#define GET_STA_FLAG(s) ((s >> 16) & 0xFF)
#define SET_STA_FLAG(s, v) (s = (s & 0xFF00FFFF) | (((v) & 0xFF) << 16))
#define GET_STA_ERR(s) ((s >> 24) & 0xFF)
#define SET_STA_ERR(s, v) (s = (s & 0x00FFFFFF) | (((v) & 0xFF) << 24))
typedef enum
{
CMD_RUN_OTA = 1,
CMD_RUN_BOOT,
CMD_RUN_VERIFY,
} OTA_CMD;
typedef enum
{
FLAG_NORMAL = 0,
FLAG_EXEC_OTA = 1,
} OTA_FLAG;
typedef enum
{
ERR_OK = 0,
ERR_BAD_BOOT_FILESIZE,
ERR_BAD_BOOT_CHKSUM,
ERR_WRITE_BOOTIMG,
ERR_BAD_ROOTFS_FILESIZE,
ERR_BAD_ROOTFS_CHKSUM,
ERR_WRITE_ROOTFSIMG,
ERR_PARAMS_UNINIT,
ERR_BAD_PARAMS_CHKSUM,
ERR_READ_PARAMS,
} OTA_ERRCODE;
typedef struct
{
char tags[8];
int otaStatus;
unsigned int otaStatus;
char otaVer[MD5_STR_LEN];
char bootChksum[MD5_STR_LEN];
unsigned int bootfileSize;
@ -40,7 +79,8 @@ static const char hex_asc[] = "0123456789abcdef";
static char* __bin2hex(char* p, unsigned char* cp, int count)
{
while (count) {
while(count)
{
unsigned char c = *cp++;
/* put lowercase hex digits */
*p++ = 0x20 | hex_asc[c >> 4];
@ -62,7 +102,7 @@ static void ota_print_params(POTA_PARAMS pInfo)
printf("rootfs_size: %u\n", pInfo->rootfsfileSize);
}
static int ota_load_boot_partition(POTA_PARAMS pInfo)
static int ota_load_boot_partition(POTA_PARAMS pInfo, int len)
{
unsigned char md5sum[MD5_CHKSUM_LEN];
char cmdBuf[128];
@ -73,16 +113,18 @@ static int ota_load_boot_partition(POTA_PARAMS pInfo)
sprintf(cmdBuf, "sunxi_flash read 0x%x boot", READ_BOOT_ADDR);
run_command(cmdBuf, 0);
if(pInfo->bootfileSize == 0)
pInfo->bootfileSize = iSize * MBR_PAGE_SIZE;
if(len <= 0)
{
len = iSize * MBR_PAGE_SIZE;
}
md5((unsigned char*)READ_BOOT_ADDR, (int)pInfo->bootfileSize, md5sum);
md5((unsigned char*)READ_BOOT_ADDR, len, md5sum);
__bin2hex(pInfo->bootChksum, md5sum, MD5_CHKSUM_LEN);
return 0;
}
static int ota_load_rootfs_partition(POTA_PARAMS pInfo)
static int ota_load_rootfs_partition(POTA_PARAMS pInfo, int len)
{
unsigned char md5sum[MD5_CHKSUM_LEN];
char cmdBuf[128];
@ -93,10 +135,12 @@ static int ota_load_rootfs_partition(POTA_PARAMS pInfo)
sprintf(cmdBuf, "sunxi_flash read 0x%x rootfs", READ_ROOTFS_ADDR);
run_command(cmdBuf, 0);
if(pInfo->rootfsfileSize == 0)
pInfo->rootfsfileSize = iSize * MBR_PAGE_SIZE;
if(len <= 0)
{
len = iSize * MBR_PAGE_SIZE;
}
md5((unsigned char*)READ_ROOTFS_ADDR, (int)pInfo->rootfsfileSize, md5sum);
md5((unsigned char*)READ_ROOTFS_ADDR, len, md5sum);
__bin2hex(pInfo->rootfsChksum, md5sum, MD5_CHKSUM_LEN);
return 0;
@ -128,6 +172,7 @@ static int ota_save_params(POTA_PARAMS pInfo)
int iSize = (sizeof(OTA_PARAMS) + MBR_PAGE_SIZE - 1) / MBR_PAGE_SIZE;
u32 start_block = sunxi_partition_get_offset_byname("ota_info");
ota_calc_params_checksum(pInfo);
sunxi_flash_write(start_block, iSize, pInfo);
sunxi_flash_flush();
@ -149,11 +194,14 @@ static int ota_erase_partition(const char* pPart)
static int ota_read_params(POTA_PARAMS pInfo)
{
char cmdBuf[128];
int init_params = 0;
memset(cmdBuf, 0, 128);
sprintf(cmdBuf, "sunxi_flash read 0x%x ota_info", READ_OTA_PARAMS_ADDR);
run_command(cmdBuf, 0);
if(run_command(cmdBuf, 0) != 0)
{
printf("Read OTA params partition error\n");
return -ERR_READ_PARAMS;
}
memcpy(pInfo, (unsigned char*)READ_OTA_PARAMS_ADDR, sizeof(OTA_PARAMS));
@ -163,31 +211,16 @@ static int ota_read_params(POTA_PARAMS pInfo)
if(ota_verify_params_checksum(pInfo) != 0)
{
init_params = 1;
printf("verify ota information error\n");
return -ERR_BAD_PARAMS_CHKSUM;
}
printf("found ota information\n");
return ERR_OK;
}
else
{
init_params = 1;
return -ERR_PARAMS_UNINIT;
}
if(init_params)
{
printf("ota system init.....\n");
memset(pInfo, 0, sizeof(OTA_PARAMS));
strcpy(pInfo->tags, OTA_PARAMS_TAG);
pInfo->otaStatus = 0;
ota_load_boot_partition(pInfo);
ota_load_rootfs_partition(pInfo);
ota_calc_params_checksum(pInfo);
ota_print_params(pInfo);
ota_save_params(pInfo);
}
return 0;
}
static int ota_read_boot_image(void)
@ -222,59 +255,223 @@ static int ota_read_rootfs_image(void)
return read_bytes;
}
static int ota_calc_image_chksum(unsigned char* addr, int iSize, char* pChksm)
static char* ota_calc_boot_image_chksum(int iSize, char* pChksum)
{
unsigned char md5sum[MD5_CHKSUM_LEN];
md5(addr, iSize, md5sum);
__bin2hex(pChksm, md5sum, MD5_CHKSUM_LEN);
md5((unsigned char*)READ_BOOT_ADDR, iSize, md5sum);
__bin2hex(pChksum, md5sum, MD5_CHKSUM_LEN);
return 0;
return pChksum;
}
static char* ota_calc_rootfs_image_chksum(int iSize, char* pChksum)
{
unsigned char md5sum[MD5_CHKSUM_LEN];
md5((unsigned char*)READ_ROOTFS_ADDR, iSize, md5sum);
__bin2hex(pChksum, md5sum, MD5_CHKSUM_LEN);
return pChksum;
}
static int ota_upgrade_boot_image(void)
{
char cmdBuf[128];
printf("Write boot image from 0x%08X to boot partition\n", READ_BOOT_ADDR);
memset(cmdBuf, 0, 128);
sprintf(cmdBuf, "sunxi_flash write 0x%x boot", READ_BOOT_ADDR);
run_command(cmdBuf, 0);
return 0;
return run_command(cmdBuf, 0);
}
static int ota_upgrade_rootfs_image(void)
{
char cmdBuf[128];
printf("Write rootfs image from 0x%08X to rootfs partition\n", READ_ROOTFS_ADDR);
memset(cmdBuf, 0, 128);
sprintf(cmdBuf, "sunxi_flash write 0x%x rootfs", READ_ROOTFS_ADDR);
run_command(cmdBuf, 0);
return run_command(cmdBuf, 0);
}
static int run_ota_upgrade(POTA_PARAMS pInfo)
{
OTA_PARAMS upgInfo;
memset(&upgInfo, 0, sizeof(OTA_PARAMS));
SET_STA_FLAG(pInfo->otaStatus, FLAG_EXEC_OTA);
upgInfo.bootfileSize = ota_read_boot_image();
ota_calc_boot_image_chksum(upgInfo.bootfileSize, upgInfo.bootChksum);
if(upgInfo.bootfileSize != pInfo->bootfileSize)
{
printf("Upgrade boot image maybe error:\n\t%s --> %s\n\t%u-%u\n",
upgInfo.bootChksum, pInfo->bootChksum,
upgInfo.bootfileSize, pInfo->bootfileSize);
SET_STA_ERR(pInfo->otaStatus, ERR_BAD_BOOT_CHKSUM);
ota_save_params(pInfo);
return -ERR_BAD_BOOT_CHKSUM;
}
else if(strcmp(upgInfo.bootChksum, pInfo->bootChksum) != 0)
{
printf("Upgrade boot image maybe error:\n\t%s --> %s\n\t%u-%u\n",
upgInfo.bootChksum, pInfo->bootChksum,
upgInfo.bootfileSize, pInfo->bootfileSize);
SET_STA_ERR(pInfo->otaStatus, ERR_BAD_BOOT_FILESIZE);
ota_save_params(pInfo);
return -ERR_BAD_BOOT_FILESIZE;
}
if(ota_upgrade_boot_image() != 0)
{
printf("Write boot image error\n");
SET_STA_ERR(pInfo->otaStatus, ERR_WRITE_BOOTIMG);
ota_save_params(pInfo);
return -ERR_WRITE_BOOTIMG;
}
upgInfo.rootfsfileSize = ota_read_rootfs_image();
ota_calc_rootfs_image_chksum(upgInfo.rootfsfileSize, upgInfo.rootfsChksum);
if(upgInfo.rootfsfileSize != pInfo->rootfsfileSize)
{
printf("Upgrade rootfs image maybe error:\n\t%s --> %s\n\t%u-%u\n",
upgInfo.rootfsChksum, pInfo->rootfsChksum,
upgInfo.rootfsfileSize, pInfo->rootfsfileSize);
SET_STA_ERR(pInfo->otaStatus, ERR_BAD_ROOTFS_FILESIZE);
ota_save_params(pInfo);
return -ERR_BAD_ROOTFS_FILESIZE;
}
else if(strcmp(upgInfo.rootfsChksum, pInfo->rootfsChksum) != 0)
{
printf("Upgrade rootfs image maybe error:\n\t%s --> %s\n\t%u-%u\n",
upgInfo.rootfsChksum, pInfo->rootfsChksum,
upgInfo.rootfsfileSize, pInfo->rootfsfileSize);
SET_STA_ERR(pInfo->otaStatus, ERR_BAD_ROOTFS_CHKSUM);
ota_save_params(pInfo);
return -ERR_BAD_ROOTFS_CHKSUM;
}
if(ota_upgrade_rootfs_image() != 0)
{
printf("Write rootfs image error\n");
SET_STA_ERR(pInfo->otaStatus, ERR_WRITE_ROOTFSIMG);
ota_save_params(pInfo);
return -ERR_WRITE_ROOTFSIMG;
}
return 0;
}
static int prepare_ota_boot(POTA_PARAMS pInfo)
{
unsigned char val = GET_STA_CNT(pInfo->otaStatus) + 1;
#if 0
static int ota_read_file(const char* pDev, const char* pPart, const char* pFile)
SET_STA_CNT(pInfo->otaStatus, val);
SET_STA_CMD(pInfo->otaStatus, CMD_RUN_BOOT);
ota_save_params(pInfo);
ota_print_params(pInfo);
return 0;
}
static int verify_ota_upgrade(POTA_PARAMS pInfo)
{
OTA_PARAMS upgInfo;
memset(&upgInfo, 0, sizeof(OTA_PARAMS));
ota_load_boot_partition(&upgInfo, pInfo->bootfileSize);
ota_load_rootfs_partition(&upgInfo, pInfo->rootfsfileSize);
if(strcmp(upgInfo.bootChksum, pInfo->bootChksum) != 0)
{
printf("Verify BOOT image MD5 Error:\n\t%s --> %s\n",
upgInfo.bootChksum, pInfo->bootChksum);
return -ERR_BAD_BOOT_CHKSUM;
}
else
{
printf("Verify BOOT image MD5 checksum successed:\n\t%s --> %s\n",
upgInfo.bootChksum, pInfo->bootChksum);
}
if(strcmp(upgInfo.rootfsChksum, pInfo->rootfsChksum) != 0)
{
printf("Verify ROOTFS image MD5 Error:\n\t%s --> %s\n",
upgInfo.rootfsChksum, pInfo->rootfsChksum);
return -ERR_BAD_ROOTFS_CHKSUM;
}
else
{
printf("Verify ROOTFS image MD5 checksum successed:\n\t%s --> %s\n",
upgInfo.rootfsChksum, pInfo->rootfsChksum);
}
return ERR_OK;
}
static int run_ota_task(void)
{
OTA_PARAMS otaInfo;
int read_bytes = 0;
if (fs_set_blk_dev(pDev, pPart, FS_TYPE_EXT))
printf("Netease: Read OTA params from ota_info partition\n");
if(ota_read_params(&otaInfo) != ERR_OK)
{
return -1;
printf("Netease: Set OTA params to default value\n");
memset(&otaInfo, 0, sizeof(OTA_PARAMS));
strcpy(otaInfo.tags, OTA_PARAMS_TAG);
SET_STA_CMD(otaInfo.otaStatus, CMD_RUN_BOOT);
SET_STA_CNT(otaInfo.otaStatus, 1);
ota_save_params(&otaInfo);
return 0;
}
read_bytes = fs_read(pFile, READ_BOOT_ADDR, 0, 0);
printf("Read %s to 0x%08X total 0x%X bytes\n", pFile, READ_BOOT_ADDR, read_bytes);
ota_read_params(&otaInfo);
return read_bytes;
if(GET_STA_CMD(otaInfo.otaStatus) == CMD_RUN_OTA)
{
printf("Netease: Run OTA upgrade system\n");
if(run_ota_upgrade(&otaInfo) != ERR_OK)
{
int val = GET_STA_CNT(otaInfo.otaStatus) + 1;
SET_STA_CNT(otaInfo.otaStatus, val);
}
#endif
int do_ota(cmd_tbl_t *cmdtp, int flag, int argc,
else
{
SET_STA_CNT(otaInfo.otaStatus, 0);
SET_STA_CMD(otaInfo.otaStatus, CMD_RUN_VERIFY);
}
ota_save_params(&otaInfo);
run_command("reset", 0);
}
else if(GET_STA_CMD(otaInfo.otaStatus) == CMD_RUN_VERIFY)
{
printf("Netease: Run OTA verify images\n");
if(verify_ota_upgrade(&otaInfo) != ERR_OK)
{
run_command("ota_cmd prepare", 0);
run_command("reset", 0);
}
else
{
SET_STA_CNT(otaInfo.otaStatus, 0);
SET_STA_CMD(otaInfo.otaStatus, CMD_RUN_BOOT);
ota_save_params(&otaInfo);
run_command("reset", 0);
}
}
printf("Netease: Set OTA system setup params\n");
return prepare_ota_boot(&otaInfo);
}
int do_ota_cmd(cmd_tbl_t* cmdtp, int flag, int argc,
char* const argv[])
{
static int read_boot_size = 0, read_rootfs_size = 0;
@ -282,7 +479,9 @@ int do_ota(cmd_tbl_t *cmdtp, int flag, int argc,
printf("ota cmd: argc = %d\n", argc);
if(argc < 2)
{
return CMD_RET_USAGE;
}
if(strncmp(argv[1], "erase", strlen("erase")) == 0)
{
@ -373,13 +572,9 @@ int do_ota(cmd_tbl_t *cmdtp, int flag, int argc,
if(flag & (1 << 0))
{
printf("%s(%d)\n", __FUNCTION__, __LINE__);
upgInfo.bootfileSize = ota_read_boot_image();
printf("%s(%d)\n", __FUNCTION__, __LINE__);
ota_calc_image_chksum((unsigned char*)READ_BOOT_ADDR,
upgInfo.bootfileSize, upgInfo.bootChksum);
printf("%s(%d)\n", __FUNCTION__, __LINE__);
ota_calc_boot_image_chksum(upgInfo.bootfileSize, upgInfo.bootChksum);
if(strcmp(upgInfo.bootChksum, otaInfo.bootChksum) != 0
|| upgInfo.bootfileSize != otaInfo.bootfileSize)
{
@ -392,19 +587,15 @@ int do_ota(cmd_tbl_t *cmdtp, int flag, int argc,
return CMD_RET_FAILURE;
}
}
printf("%s(%d)\n", __FUNCTION__, __LINE__);
ota_upgrade_boot_image();
printf("%s(%d)\n", __FUNCTION__, __LINE__);
}
if(flag & (1 << 1))
{
printf("%s(%d)\n", __FUNCTION__, __LINE__);
upgInfo.rootfsfileSize = ota_read_rootfs_image();
printf("%s(%d)\n", __FUNCTION__, __LINE__);
ota_calc_image_chksum((unsigned char*)READ_ROOTFS_ADDR,
upgInfo.rootfsfileSize, upgInfo.rootfsChksum);
printf("%s(%d)\n", __FUNCTION__, __LINE__);
ota_calc_rootfs_image_chksum(upgInfo.rootfsfileSize, upgInfo.rootfsChksum);
if(strcmp(upgInfo.rootfsChksum, otaInfo.rootfsChksum) != 0
|| upgInfo.rootfsfileSize != otaInfo.rootfsfileSize)
{
@ -421,6 +612,32 @@ int do_ota(cmd_tbl_t *cmdtp, int flag, int argc,
ota_upgrade_rootfs_image();
}
}
else if(strncmp(argv[1], "prepare", strlen("init_ota")) == 0)
{
OTA_PARAMS otaInfo;
memset(&otaInfo, 0, sizeof(OTA_PARAMS));
strcpy(otaInfo.tags, OTA_PARAMS_TAG);
if(argc == 2)
{
strcpy(otaInfo.otaVer, "0.0.0.0");
}
else
{
strcpy(otaInfo.otaVer, argv[2]);
}
SET_STA_CNT(otaInfo.otaStatus, 0);
SET_STA_CMD(otaInfo.otaStatus, CMD_RUN_OTA);
SET_STA_FLAG(otaInfo.otaStatus, 0);
SET_STA_ERR(otaInfo.otaStatus, ERR_OK);
otaInfo.bootfileSize = ota_read_boot_image();
otaInfo.rootfsfileSize = ota_read_rootfs_image();
ota_calc_boot_image_chksum(otaInfo.bootfileSize, otaInfo.bootChksum);
ota_calc_rootfs_image_chksum(otaInfo.rootfsfileSize, otaInfo.rootfsChksum);
ota_print_params(&otaInfo);
ota_save_params(&otaInfo);
}
else
{
return CMD_RET_USAGE;
@ -430,8 +647,13 @@ int do_ota(cmd_tbl_t *cmdtp, int flag, int argc,
return 0;
}
int do_ota_setup(cmd_tbl_t* cmdtp, int flag, int argc,
char* const argv[])
{
return run_ota_task();
}
U_BOOT_CMD(ota, 5, 0, do_ota,
U_BOOT_CMD(ota_setup, 1, 0, do_ota_setup,
"netease OTA command:",
"<command> <parmeters>\n"
" erase <partiton name>\n"
@ -440,6 +662,24 @@ U_BOOT_CMD(ota, 5, 0, do_ota,
" - read ota image form UDISK file system\n"
" upgrade <boot/rootfs/all> [0/1(skip verify chksum)]\n"
" - read ota image form UDISK file system and upgrade nand partiton\n"
" prepare\n"
" - set ota opeartion from current system\n"
" show_params\n"
" - show ota params information\n"
" - *********************************************");
U_BOOT_CMD(ota_cmd, 5, 0, do_ota_cmd,
"netease OTA command:",
"<command> <parmeters>\n"
" erase <partiton name>\n"
" - erase mtd partiton\n"
" read <boot/rootfs>\n"
" - read ota image form UDISK file system\n"
" upgrade <boot/rootfs/all> [0/1(skip verify chksum)]\n"
" - read ota image form UDISK file system and upgrade nand partiton\n"
" prepare\n"
" - set ota opeartion from current system\n"
" show_params\n"
" - show ota params information\n"
" - *********************************************");

View File

@ -1,6 +1,6 @@
bootdelay=3
#default bootcmd, will change at runtime according to key press
bootcmd=run setargs_nand boot_normal#default nand boot
bootcmd=run setargs_nand ota_setup boot_normal#default nand boot
#kernel command arguments
console=ttyS0,115200
nor_root=/dev/mtdblock4

View File

@ -81,6 +81,11 @@ size = 512
size = 1024
user_type = 0x8000
[partition]
name = private
size = 1024
user_type = 0x8000
[partition]
name = UDISK
user_type = 0x8100