1747 lines
48 KiB
C
Executable File
1747 lines
48 KiB
C
Executable File
/*
|
||
* (C) Copyright 2007-2013
|
||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||
* Jerry Wang <wangflord@allwinnertech.com>
|
||
*
|
||
* See file CREDITS for list of people who contributed to this
|
||
* project.
|
||
*
|
||
* This program is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU General Public License as
|
||
* published by the Free Software Foundation; either version 2 of
|
||
* the License, or (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||
* MA 02111-1307 USA
|
||
*/
|
||
#include <config.h>
|
||
#include <common.h>
|
||
#include <malloc.h>
|
||
#include "sparse/sparse.h"
|
||
#include <asm/arch/queue.h>
|
||
#include <sunxi_mbr.h>
|
||
#include <sys_partition.h>
|
||
#include <private_boot0.h>
|
||
#include <private_uboot.h>
|
||
#include "encrypt/encrypt.h"
|
||
#include "sprite_queue.h"
|
||
#include "sprite_download.h"
|
||
#include "sprite_verify.h"
|
||
#include "firmware/imgdecode.h"
|
||
#include "dos_part.h"
|
||
#include <boot_type.h>
|
||
#include <mmc.h>
|
||
#include <sys_config.h>
|
||
#include <private_boot0.h>
|
||
#include <sunxi_board.h>
|
||
|
||
#define SPRITE_CARD_HEAD_BUFF (32 * 1024)
|
||
#if defined (CONFIG_SUNXI_SPINOR)
|
||
#define SPRITE_CARD_ONCE_DATA_DEAL (2 * 1024 * 1024)
|
||
#else
|
||
#define SPRITE_CARD_ONCE_DATA_DEAL (16 * 1024 * 1024)
|
||
#endif
|
||
#define SPRITE_CARD_ONCE_SECTOR_DEAL (SPRITE_CARD_ONCE_DATA_DEAL/512)
|
||
|
||
static void *imghd = NULL;
|
||
static void *imgitemhd = NULL;
|
||
|
||
DECLARE_GLOBAL_DATA_PTR;
|
||
|
||
//extern int sunxi_flash_mmc_phywipe(unsigned long start_block, unsigned long nblock, unsigned long *skip);
|
||
static int __download_normal_part(dl_one_part_info *part_info, uchar *source_buff);
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
uint sprite_card_firmware_start(void)
|
||
{
|
||
return sunxi_partition_get_offset(1);
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sprite_card_firmware_probe(char *name)
|
||
{
|
||
debug("firmware name %s\n", name);
|
||
imghd = Img_Open(name);
|
||
if(!imghd)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sprite_card_fetch_download_map(sunxi_download_info *dl_map)
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "1234567890DLINFO");
|
||
if(!imgitemhd)
|
||
{
|
||
return -1;
|
||
}
|
||
debug("try to read item dl map\n");
|
||
if(!Img_ReadItem(imghd, imgitemhd, (void *)dl_map, sizeof(sunxi_download_info)))
|
||
{
|
||
printf("sunxi sprite error : read dl map failed\n");
|
||
|
||
return -1;
|
||
}
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
//检查获取的dlinfo是否正确
|
||
return sunxi_sprite_verify_dlmap(dl_map);
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sprite_card_fetch_mbr(void *img_mbr)
|
||
{
|
||
int mbr_num = SUNXI_MBR_COPY_NUM;
|
||
|
||
if (get_boot_storage_type() == STORAGE_NOR)
|
||
{
|
||
mbr_num = 1;
|
||
}
|
||
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "1234567890___MBR");
|
||
if(!imgitemhd)
|
||
{
|
||
return -1;
|
||
}
|
||
debug("try to read item mbr\n");
|
||
if(!Img_ReadItem(imghd, imgitemhd, img_mbr, sizeof(sunxi_mbr_t) * mbr_num))
|
||
{
|
||
printf("sunxi sprite error : read mbr failed\n");
|
||
|
||
return -1;
|
||
}
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
|
||
return sunxi_sprite_verify_mbr(img_mbr);
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __download_udisk(dl_one_part_info *part_info, uchar *source_buff)
|
||
{
|
||
HIMAGEITEM imgitemhd = NULL;
|
||
u32 flash_sector;
|
||
s64 packet_len;
|
||
s32 ret = -1, ret1;
|
||
|
||
//打开分区镜像
|
||
imgitemhd = Img_OpenItem(imghd, "RFSFAT16", (char *)part_info->dl_filename);
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sunxi sprite error: open part %s failed\n", part_info->dl_filename);
|
||
|
||
return -1;
|
||
}
|
||
//获取分区镜像字节数
|
||
packet_len = Img_GetItemSize(imghd, imgitemhd);
|
||
if (packet_len <= 0)
|
||
{
|
||
printf("sunxi sprite error: fetch part len %s failed\n", part_info->dl_filename);
|
||
|
||
goto __download_udisk_err1;
|
||
}
|
||
if (packet_len <= FW_BURN_UDISK_MIN_SIZE)
|
||
{
|
||
printf("download UDISK: the data length of udisk is too small, ignore it\n");
|
||
|
||
ret = 1;
|
||
goto __download_udisk_err1;
|
||
}
|
||
//分区镜像够大,需要进行烧录
|
||
flash_sector = sunxi_sprite_size();
|
||
if(!flash_sector)
|
||
{
|
||
printf("sunxi sprite error: download_udisk, the flash size is invalid(0)\n");
|
||
|
||
goto __download_udisk_err1;
|
||
}
|
||
printf("the flash size is %d MB\n", flash_sector/2/1024); //计算出M单位
|
||
part_info->lenlo = flash_sector - part_info->addrlo;
|
||
part_info->lenhi = 0;
|
||
printf("UDISK low is 0x%x Sectors\n", part_info->lenlo);
|
||
printf("UDISK high is 0x%x Sectors\n", part_info->lenhi);
|
||
|
||
ret = __download_normal_part(part_info, source_buff);
|
||
__download_udisk_err1:
|
||
ret1 = Img_CloseItem(imghd, imgitemhd);
|
||
if(ret1 != 0 )
|
||
{
|
||
printf("sunxi sprite error: __download_udisk, close udisk image failed\n");
|
||
|
||
return -1;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __download_normal_part(dl_one_part_info *part_info, uchar *source_buff)
|
||
{
|
||
uint partstart_by_sector; //分区起始扇区
|
||
uint tmp_partstart_by_sector;
|
||
|
||
s64 partsize_by_byte; //分区大小(字节单位)
|
||
|
||
s64 partdata_by_byte; //需要下载的分区数据(字节单位)
|
||
s64 tmp_partdata_by_bytes;
|
||
|
||
uint onetime_read_sectors; //一次读写的扇区数
|
||
uint first_write_bytes;
|
||
|
||
uint imgfile_start; //分区数据所在的扇区
|
||
uint tmp_imgfile_start;
|
||
|
||
u8 *down_buffer = source_buff + SPRITE_CARD_HEAD_BUFF;
|
||
|
||
int partdata_format;
|
||
|
||
int ret = -1;
|
||
//*******************************************************************
|
||
//获取分区起始扇区
|
||
tmp_partstart_by_sector = partstart_by_sector = part_info->addrlo;
|
||
//获取分区大小,字节数
|
||
partsize_by_byte = part_info->lenlo;
|
||
partsize_by_byte <<= 9;
|
||
//打开分区镜像
|
||
imgitemhd = Img_OpenItem(imghd, "RFSFAT16", (char *)part_info->dl_filename);
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sunxi sprite error: open part %s failed\n", part_info->dl_filename);
|
||
|
||
return -1;
|
||
}
|
||
//获取分区镜像字节数
|
||
partdata_by_byte = Img_GetItemSize(imghd, imgitemhd);
|
||
if (partdata_by_byte <= 0)
|
||
{
|
||
printf("sunxi sprite error: fetch part len %s failed\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
printf("partdata hi 0x%x\n", (uint)(partdata_by_byte>>32));
|
||
printf("partdata lo 0x%x\n", (uint)partdata_by_byte);
|
||
//如果分区数据超过分区大小
|
||
if(partdata_by_byte > partsize_by_byte)
|
||
{
|
||
printf("sunxi sprite: data size 0x%x is larger than part %s size 0x%x\n", (uint)(partdata_by_byte/512), part_info->dl_filename, (uint)(partsize_by_byte/512));
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
//准备读取分区镜像数据
|
||
tmp_partdata_by_bytes = partdata_by_byte;
|
||
if(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
first_write_bytes = SPRITE_CARD_ONCE_DATA_DEAL;
|
||
}
|
||
else
|
||
{
|
||
onetime_read_sectors = (tmp_partdata_by_bytes + 511)>>9;
|
||
first_write_bytes = (uint)tmp_partdata_by_bytes;
|
||
}
|
||
//开始获取分区数据
|
||
imgfile_start = Img_GetItemStart(imghd, imgitemhd);
|
||
if(!imgfile_start)
|
||
{
|
||
printf("sunxi sprite err : cant get part data imgfile_start %s\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
tmp_imgfile_start = imgfile_start;
|
||
//读出第一笔固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, onetime_read_sectors, down_buffer) != onetime_read_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, onetime_read_sectors);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
//下一个要读出的数据
|
||
tmp_imgfile_start += onetime_read_sectors;
|
||
//尝试查看是否sparse格式
|
||
partdata_format = unsparse_probe((char *)down_buffer, first_write_bytes, partstart_by_sector); //判断数据格式
|
||
if(partdata_format != ANDROID_FORMAT_DETECT)
|
||
{
|
||
//写入第一笔数据
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, onetime_read_sectors, down_buffer) != onetime_read_sectors)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error %s\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
tmp_partdata_by_bytes -= first_write_bytes;
|
||
tmp_partstart_by_sector += onetime_read_sectors;
|
||
|
||
while(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
//继续读出固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
//写入flash
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x\n", part_info->dl_filename, tmp_partstart_by_sector, SPRITE_CARD_ONCE_SECTOR_DEAL);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
tmp_imgfile_start += SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
tmp_partdata_by_bytes -= SPRITE_CARD_ONCE_DATA_DEAL;
|
||
tmp_partstart_by_sector += SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
}
|
||
if(tmp_partdata_by_bytes > 0)
|
||
{
|
||
uint rest_sectors = (tmp_partdata_by_bytes + 511)>>9;
|
||
//继续读出固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, rest_sectors);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
//写入flash
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x\n", part_info->dl_filename, tmp_partstart_by_sector, rest_sectors);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(unsparse_direct_write(down_buffer, first_write_bytes))
|
||
{
|
||
printf("sunxi sprite error: download sparse error %s\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
tmp_partdata_by_bytes -= first_write_bytes;
|
||
|
||
while(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
//继续读出固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block 0x%x, total 0x%x failed\n", tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
//写入flash
|
||
if(unsparse_direct_write(down_buffer, SPRITE_CARD_ONCE_DATA_DEAL))
|
||
{
|
||
printf("sunxi sprite error: download sparse error %s\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
tmp_imgfile_start += SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
tmp_partdata_by_bytes -= SPRITE_CARD_ONCE_DATA_DEAL;
|
||
}
|
||
if(tmp_partdata_by_bytes > 0)
|
||
{
|
||
uint rest_sectors = (tmp_partdata_by_bytes + 511)>>9;
|
||
//继续读出固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block 0x%x, total 0x%x failed\n", tmp_imgfile_start, rest_sectors);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
//写入flash
|
||
if(unsparse_direct_write(down_buffer, tmp_partdata_by_bytes))
|
||
{
|
||
printf("sunxi sprite error: download sparse error %s\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
}
|
||
}
|
||
|
||
tick_printf("successed in writting part %s\n", part_info->name);
|
||
ret = 0;
|
||
if(imgitemhd)
|
||
{
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
}
|
||
//判断是否需要进行校验
|
||
if(part_info->verify)
|
||
{
|
||
uint active_verify;
|
||
uint origin_verify;
|
||
uchar verify_data[1024];
|
||
|
||
ret = -1;
|
||
if(part_info->vf_filename[0])
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "RFSFAT16", (char *)part_info->vf_filename);
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sprite update warning: open part %s failed\n", part_info->vf_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
if(!Img_ReadItem(imghd, imgitemhd, (void *)verify_data, 1024)) //读出数据
|
||
{
|
||
printf("sprite update warning: fail to read data from %s\n", part_info->vf_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
if(partdata_format == ANDROID_FORMAT_DETECT)
|
||
{
|
||
active_verify = sunxi_sprite_part_sparsedata_verify();
|
||
}
|
||
else
|
||
{
|
||
active_verify = sunxi_sprite_part_rawdata_verify(partstart_by_sector, partdata_by_byte);
|
||
}
|
||
{
|
||
uint *tmp = (uint *)verify_data;
|
||
|
||
origin_verify = *tmp;
|
||
}
|
||
printf("origin_verify value = %x, active_verify value = %x\n", origin_verify, active_verify);
|
||
if(origin_verify != active_verify)
|
||
{
|
||
printf("origin checksum=%x, active checksum=%x\n", origin_verify, active_verify);
|
||
printf("sunxi sprite: part %s verify error\n", part_info->dl_filename);
|
||
|
||
goto __download_normal_part_err1;
|
||
}
|
||
ret = 0;
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi sprite err: part %s unablt to find verify file\n", part_info->dl_filename);
|
||
}
|
||
tick_printf("successed in verify part %s\n", part_info->name);
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi sprite err: part %s not need to verify\n", part_info->dl_filename);
|
||
}
|
||
|
||
__download_normal_part_err1:
|
||
if(imgitemhd)
|
||
{
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __download_sysrecover_part(dl_one_part_info *part_info, uchar *source_buff)
|
||
{
|
||
uint partstart_by_sector; //分区起始扇区
|
||
uint tmp_partstart_by_sector;
|
||
|
||
s64 partsize_by_byte; //分区大小(字节单位)
|
||
|
||
s64 partdata_by_byte; //需要下载的分区数据(字节单位)
|
||
s64 tmp_partdata_by_bytes;
|
||
|
||
uint onetime_read_sectors; //一次读写的扇区数
|
||
|
||
uint imgfile_start; //分区数据所在的扇区
|
||
uint tmp_imgfile_start;
|
||
|
||
u8 *down_buffer = source_buff + SPRITE_CARD_HEAD_BUFF;
|
||
|
||
int ret = -1;
|
||
//*******************************************************************
|
||
//获取分区起始扇区
|
||
tmp_partstart_by_sector = partstart_by_sector = part_info->addrlo;
|
||
//获取分区大小,字节数
|
||
partsize_by_byte = part_info->lenlo;
|
||
partsize_by_byte <<= 9;
|
||
//打开分区镜像
|
||
|
||
//获取分区镜像字节数
|
||
partdata_by_byte = Img_GetSize(imghd);
|
||
if (partdata_by_byte <= 0)
|
||
{
|
||
printf("sunxi sprite error: fetch part len %s failed\n", part_info->dl_filename);
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
//如果分区数据超过分区大小
|
||
if(partdata_by_byte > partsize_by_byte)
|
||
{
|
||
printf("sunxi sprite: data size 0x%x is larger than part %s size 0x%x\n", (uint)(partdata_by_byte/512), part_info->dl_filename, (uint)(partsize_by_byte/512));
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
//准备读取分区镜像数据
|
||
tmp_partdata_by_bytes = partdata_by_byte;
|
||
if(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
}
|
||
else
|
||
{
|
||
onetime_read_sectors = (tmp_partdata_by_bytes + 511)>>9;
|
||
}
|
||
//开始获取分区数据
|
||
imgfile_start = sprite_card_firmware_start();
|
||
if(!imgfile_start)
|
||
{
|
||
printf("sunxi sprite err : cant get part data imgfile_start %s\n", part_info->dl_filename);
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
tmp_imgfile_start = imgfile_start;
|
||
|
||
while(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
//继续读出固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, onetime_read_sectors, down_buffer) != onetime_read_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, onetime_read_sectors);
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
//写入flash
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, onetime_read_sectors, down_buffer) != onetime_read_sectors)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x\n", part_info->dl_filename, tmp_partstart_by_sector, onetime_read_sectors);
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
tmp_imgfile_start += onetime_read_sectors;
|
||
tmp_partdata_by_bytes -= onetime_read_sectors*512;
|
||
tmp_partstart_by_sector += onetime_read_sectors;
|
||
}
|
||
if(tmp_partdata_by_bytes > 0)
|
||
{
|
||
uint rest_sectors = (tmp_partdata_by_bytes + 511)/512;
|
||
//继续读出固件中的分区数据,大小为buffer字节数
|
||
if(sunxi_flash_read(tmp_imgfile_start, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, rest_sectors);
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
//写入flash
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x\n", part_info->dl_filename, tmp_partstart_by_sector, rest_sectors);
|
||
|
||
goto __download_sysrecover_part_err1;
|
||
}
|
||
}
|
||
ret = 0;
|
||
|
||
__download_sysrecover_part_err1:
|
||
if(imgitemhd)
|
||
{
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_sprite_deal_part(sunxi_download_info *dl_map)
|
||
{
|
||
dl_one_part_info *part_info;
|
||
int ret = -1;
|
||
int ret1;
|
||
int i = 0;
|
||
uchar *down_buff = NULL;
|
||
int rate;
|
||
|
||
if(!dl_map->download_count)
|
||
{
|
||
printf("sunxi sprite: no part need to write\n");
|
||
|
||
return 0;
|
||
}
|
||
rate = (70-10)/dl_map->download_count;
|
||
//初始化flash,nand或者mmc
|
||
if(sunxi_sprite_init(1))
|
||
{
|
||
printf("sunxi sprite err: init flash err\n");
|
||
|
||
return -1;
|
||
}
|
||
//申请内存
|
||
down_buff = (uchar *)malloc(SPRITE_CARD_ONCE_DATA_DEAL + SPRITE_CARD_HEAD_BUFF);
|
||
if(!down_buff)
|
||
{
|
||
printf("sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part\n");
|
||
|
||
goto __sunxi_sprite_deal_part_err1;
|
||
}
|
||
for(part_info = dl_map->one_part_info, i = 0; i < dl_map->download_count; i++, part_info++)
|
||
{
|
||
tick_printf("begin to download part %s\n", part_info->name);
|
||
if(!strncmp("UDISK", (char*)part_info->name, strlen("UDISK")))
|
||
{
|
||
ret1 = __download_udisk(part_info, down_buff);
|
||
if(ret1 < 0)
|
||
{
|
||
printf("sunxi sprite err: sunxi_sprite_deal_part, download_udisk failed\n");
|
||
|
||
goto __sunxi_sprite_deal_part_err2;
|
||
}
|
||
else if(ret1 > 0)
|
||
{
|
||
printf("do NOT need download UDISK\n");
|
||
}
|
||
}//如果是sysrecovery分区,烧录完整分区镜像
|
||
else if(!strncmp("sysrecovery", (char*)part_info->name, strlen("sysrecovery")))
|
||
{
|
||
ret1 = __download_sysrecover_part(part_info, down_buff);
|
||
if(ret1 != 0)
|
||
{
|
||
printf("sunxi sprite err: sunxi_sprite_deal_part, download sysrecovery failed\n");
|
||
|
||
goto __sunxi_sprite_deal_part_err2;
|
||
}
|
||
}//如果是private分区,检查是否需要烧录
|
||
else if(!strncmp("private", (char*)part_info->name, strlen("private")))
|
||
{
|
||
if(1)
|
||
{
|
||
//需要烧录此分区
|
||
printf("NEED down private part\n");
|
||
ret1 = __download_normal_part(part_info, down_buff);
|
||
if(ret1 != 0)
|
||
{
|
||
printf("sunxi sprite err: sunxi_sprite_deal_part, download private failed\n");
|
||
|
||
goto __sunxi_sprite_deal_part_err2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("IGNORE private part\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ret1 = __download_normal_part(part_info, down_buff);
|
||
if(ret1 != 0)
|
||
{
|
||
printf("sunxi sprite err: sunxi_sprite_deal_part, download normal failed\n");
|
||
|
||
goto __sunxi_sprite_deal_part_err2;
|
||
}
|
||
}
|
||
sprite_cartoon_upgrade(10 + rate * (i+1));
|
||
tick_printf("successed in download part %s\n", part_info->name);
|
||
}
|
||
|
||
ret = 0;
|
||
|
||
__sunxi_sprite_deal_part_err1:
|
||
sunxi_sprite_exit(1);
|
||
|
||
__sunxi_sprite_deal_part_err2:
|
||
|
||
if(down_buff)
|
||
{
|
||
free(down_buff);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_sprite_deal_uboot(int production_media)
|
||
{
|
||
char buffer[4 * 1024 * 1024];
|
||
uint item_original_size;
|
||
if(gd->bootfile_mode == SUNXI_BOOT_FILE_NORMAL )
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "UBOOT_0000000000");
|
||
}
|
||
else if(gd->bootfile_mode == SUNXI_BOOT_FILE_PKG)
|
||
{
|
||
if (get_boot_storage_type() != STORAGE_NOR)
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "BOOTPKG-00000000");
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "BOOTPKG-NOR00000");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "TOC1_00000000000");
|
||
}
|
||
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sprite update error: fail to open uboot item\n");
|
||
return -1;
|
||
}
|
||
//uboot长度
|
||
item_original_size = Img_GetItemSize(imghd, imgitemhd);
|
||
if(!item_original_size)
|
||
{
|
||
printf("sprite update error: fail to get uboot item size\n");
|
||
return -1;
|
||
}
|
||
/*获取uboot的数据*/
|
||
if(!Img_ReadItem(imghd, imgitemhd, (void *)buffer, 4 * 1024 * 1024))
|
||
{
|
||
printf("update error: fail to read data from for uboot\n");
|
||
return -1;
|
||
}
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
|
||
if(sunxi_sprite_download_uboot(buffer, production_media, 0))
|
||
{
|
||
printf("update error: fail to write uboot\n");
|
||
return -1;
|
||
}
|
||
printf("sunxi_sprite_deal_uboot ok\n");
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_sprite_deal_boot0(int production_media)
|
||
{
|
||
char buffer[1*1024*1024];
|
||
uint item_original_size;
|
||
|
||
if(gd->bootfile_mode == SUNXI_BOOT_FILE_NORMAL || gd->bootfile_mode == SUNXI_BOOT_FILE_PKG )
|
||
{
|
||
if(production_media == STORAGE_NAND)
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "BOOT ", "BOOT0_0000000000");
|
||
}
|
||
else if (production_media == STORAGE_NOR)
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "1234567890BNOR_0");
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "1234567890BOOT_0");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "TOC0_00000000000");
|
||
}
|
||
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sprite update error: fail to open boot0 item\n");
|
||
return -1;
|
||
}
|
||
//boot0长度
|
||
item_original_size = Img_GetItemSize(imghd, imgitemhd);
|
||
if(!item_original_size)
|
||
{
|
||
printf("sprite update error: fail to get boot0 item size\n");
|
||
return -1;
|
||
}
|
||
/*获取boot0的数据*/
|
||
if(!Img_ReadItem(imghd, imgitemhd, (void *)buffer, 1 * 1024 * 1024))
|
||
{
|
||
printf("update error: fail to read data from for boot0\n");
|
||
return -1;
|
||
}
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
|
||
if(sunxi_sprite_download_boot0(buffer, production_media))
|
||
{
|
||
printf("update error: fail to write boot0\n");
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int sunxi_sprite_deal_recorvery_boot(int production_media)
|
||
{
|
||
char buffer_uboot[4 * 1024 * 1024];
|
||
char buffer_boot0[1 *1024 * 1024];
|
||
uint item_size_uboot;
|
||
uint item_size_boot0;
|
||
if(gd->bootfile_mode == SUNXI_BOOT_FILE_NORMAL )
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "UBOOT_0000000000");
|
||
}
|
||
else if(gd->bootfile_mode == SUNXI_BOOT_FILE_PKG)
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "BOOTPKG-00000000");
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "TOC1_00000000000");
|
||
}
|
||
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sprite update error: fail to open uboot item\n");
|
||
return -1;
|
||
}
|
||
|
||
item_size_uboot = Img_GetItemSize(imghd, imgitemhd);
|
||
if(!item_size_uboot)
|
||
{
|
||
printf("sprite update error: fail to get uboot item size\n");
|
||
return -1;
|
||
}
|
||
if(!Img_ReadItem(imghd, imgitemhd, (void *)buffer_uboot, 4 * 1024 * 1024))
|
||
{
|
||
printf("update error: fail to read data from for uboot\n");
|
||
return -1;
|
||
}
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
|
||
if(gd->bootfile_mode == SUNXI_BOOT_FILE_NORMAL || gd->bootfile_mode == SUNXI_BOOT_FILE_PKG)
|
||
{
|
||
if(production_media == 0)
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "BOOT ", "BOOT0_0000000000");
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "1234567890BOOT_0");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "TOC0_00000000000");
|
||
}
|
||
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sprite update error: fail to open boot0 item\n");
|
||
return -1;
|
||
}
|
||
|
||
item_size_boot0 = Img_GetItemSize(imghd, imgitemhd);
|
||
if(!item_size_boot0)
|
||
{
|
||
printf("sprite update error: fail to get boot0 item size\n");
|
||
return -1;
|
||
}
|
||
|
||
if(!Img_ReadItem(imghd, imgitemhd, (void *)buffer_boot0, 1 * 1024 * 1024))
|
||
{
|
||
printf("update error: fail to read data from for boot0\n");
|
||
return -1;
|
||
}
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
|
||
/*write boot data*/
|
||
if(sunxi_sprite_download_uboot(buffer_uboot, production_media, 0))
|
||
{
|
||
printf("update error: fail to write uboot\n");
|
||
return -1;
|
||
}
|
||
tick_printf("successed in downloading uboot\n");
|
||
if(sunxi_sprite_download_boot0(buffer_boot0, production_media))
|
||
{
|
||
printf("update error: fail to write boot0\n");
|
||
return -1;
|
||
}
|
||
tick_printf("successed in downloading boot0\n");
|
||
printf("sunxi_sprite_deal_recorvery_boot ok\n");
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int card_download_uboot(uint length, void *buffer)
|
||
{
|
||
int ret;
|
||
|
||
ret = sunxi_sprite_phywrite(UBOOT_START_SECTOR_IN_SDMMC, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
return -1;
|
||
}
|
||
ret = sunxi_sprite_phywrite(UBOOT_BACKUP_START_SECTOR_IN_SDMMC, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int card_download_boot0(uint length, void *buffer, uint storage_type)
|
||
{
|
||
int ret = 0;
|
||
char *erase_buffer = NULL;
|
||
|
||
erase_buffer = (char *)malloc(length);
|
||
if (!erase_buffer)
|
||
{
|
||
printf("%s: malloc %d byte memory fail\n", __func__, length);
|
||
return -1;
|
||
}
|
||
memset(erase_buffer, 0, length);
|
||
|
||
//for card2
|
||
if (storage_type == STORAGE_EMMC)
|
||
{
|
||
printf("card2 download boot0 \n");
|
||
//write boot0 bankup copy firstly
|
||
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_BACKUP_START_ADDR, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_SDMMC_BACKUP_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_START_ADDR, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_SDMMC_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
|
||
#ifdef PLATFORM_SUPPORT_EMMC3
|
||
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_START_ADDR, length/512, erase_buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_EMMC3_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_BACKUP_START_ADDR, length/512, erase_buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_EMMC3_BACKUP_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
#endif
|
||
}
|
||
else if (storage_type == STORAGE_SD1)
|
||
{
|
||
printf("card1 download boot0 \n");
|
||
//write boot0 bankup copy firstly
|
||
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_BACKUP_START_ADDR, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_SDMMC_BACKUP_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_START_ADDR, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_SDMMC_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
|
||
#ifdef PLATFORM_SUPPORT_EMMC3
|
||
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_START_ADDR, length/512, erase_buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_EMMC3_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_BACKUP_START_ADDR, length/512, erase_buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_EMMC3_BACKUP_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
#endif
|
||
}
|
||
else //for card3
|
||
{
|
||
#ifdef PLATFORM_SUPPORT_EMMC3
|
||
printf("card3 download boot0 \n");
|
||
//write boot0 bankup copy firstly
|
||
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_BACKUP_START_ADDR, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_EMMC3_BACKUP_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_START_ADDR, length/512, buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_EMMC3_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
|
||
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_START_ADDR, length/512, erase_buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_SDMMC_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_BACKUP_START_ADDR, length/512, erase_buffer);
|
||
if(!ret)
|
||
{
|
||
printf("%s: write boot0 from %d fail\n", __func__, BOOT0_SDMMC_BACKUP_START_ADDR);
|
||
goto ERR_OUT;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ERR_OUT:
|
||
if (erase_buffer != NULL)
|
||
free(erase_buffer);
|
||
|
||
if (!ret)
|
||
return -1;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
//static void buffer_dump(void *buffer, int len)
|
||
//{
|
||
// int i;
|
||
// char *data = (char *)buffer;
|
||
//
|
||
// for(i=0;i<len;i++)
|
||
// {
|
||
// printf("%02x", data[i]);
|
||
// if((i & 0x07) == 7)
|
||
// {
|
||
// printf("\n");
|
||
// }
|
||
// else
|
||
// {
|
||
// puts(" ");
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
int card_download_standard_mbr(void *buffer)
|
||
{
|
||
mbr_stand *mbrst;
|
||
sunxi_mbr_t *mbr = (sunxi_mbr_t *)buffer;
|
||
char mbr_bufst[512];
|
||
int i;
|
||
int sectors;
|
||
int unusd_sectors;
|
||
|
||
sectors = 0;
|
||
for(i=1;i<mbr->PartCount-1;i++)
|
||
{
|
||
memset(mbr_bufst, 0, 512);
|
||
mbrst = (mbr_stand *)mbr_bufst;
|
||
|
||
sectors += mbr->array[i].lenlo;
|
||
|
||
mbrst->part_info[0].part_type = 0x83;
|
||
mbrst->part_info[0].start_sectorl = ((mbr->array[i].addrlo - i + 20 * 1024 * 1024/512 ) & 0x0000ffff) >> 0;
|
||
mbrst->part_info[0].start_sectorh = ((mbr->array[i].addrlo - i + 20 * 1024 * 1024/512 ) & 0xffff0000) >> 16;
|
||
mbrst->part_info[0].total_sectorsl = ( mbr->array[i].lenlo & 0x0000ffff) >> 0;
|
||
mbrst->part_info[0].total_sectorsh = ( mbr->array[i].lenlo & 0xffff0000) >> 16;
|
||
|
||
if(i != mbr->PartCount-2)
|
||
{
|
||
mbrst->part_info[1].part_type = 0x05;
|
||
mbrst->part_info[1].start_sectorl = i;
|
||
mbrst->part_info[1].start_sectorh = 0;
|
||
mbrst->part_info[1].total_sectorsl = (mbr->array[i].lenlo & 0x0000ffff) >> 0;
|
||
mbrst->part_info[1].total_sectorsh = (mbr->array[i].lenlo & 0xffff0000) >> 16;
|
||
}
|
||
|
||
mbrst->end_flag = 0xAA55;
|
||
if(!sunxi_sprite_phywrite(i, 1, mbr_bufst))
|
||
{
|
||
printf("write standard mbr %d failed\n", i);
|
||
|
||
return -1;
|
||
}
|
||
}
|
||
memset(mbr_bufst, 0, 512);
|
||
mbrst = (mbr_stand *)mbr_bufst;
|
||
|
||
unusd_sectors = sunxi_sprite_size() - 20 * 1024 * 1024/512 - sectors;
|
||
mbrst->part_info[0].indicator = 0x80;
|
||
mbrst->part_info[0].part_type = 0x0B;
|
||
mbrst->part_info[0].start_sectorl = ((mbr->array[mbr->PartCount-1].addrlo + 20 * 1024 * 1024/512 ) & 0x0000ffff) >> 0;
|
||
mbrst->part_info[0].start_sectorh = ((mbr->array[mbr->PartCount-1].addrlo + 20 * 1024 * 1024/512 ) & 0xffff0000) >> 16;
|
||
mbrst->part_info[0].total_sectorsl = ( unusd_sectors & 0x0000ffff) >> 0;
|
||
mbrst->part_info[0].total_sectorsh = ( unusd_sectors & 0xffff0000) >> 16;
|
||
|
||
mbrst->part_info[1].part_type = 0x06;
|
||
mbrst->part_info[1].start_sectorl = ((mbr->array[0].addrlo + 20 * 1024 * 1024/512) & 0x0000ffff) >> 0;
|
||
mbrst->part_info[1].start_sectorh = ((mbr->array[0].addrlo + 20 * 1024 * 1024/512) & 0xffff0000) >> 16;
|
||
mbrst->part_info[1].total_sectorsl = (mbr->array[0].lenlo & 0x0000ffff) >> 0;
|
||
mbrst->part_info[1].total_sectorsh = (mbr->array[0].lenlo & 0xffff0000) >> 16;
|
||
|
||
mbrst->part_info[2].part_type = 0x05;
|
||
mbrst->part_info[2].start_sectorl = 1;
|
||
mbrst->part_info[2].start_sectorh = 0;
|
||
mbrst->part_info[2].total_sectorsl = (sectors & 0x0000ffff) >> 0;
|
||
mbrst->part_info[2].total_sectorsh = (sectors & 0xffff0000) >> 16;
|
||
|
||
mbrst->end_flag = 0xAA55;
|
||
if(!sunxi_sprite_phywrite(0, 1, mbr_bufst))
|
||
{
|
||
printf("write standard mbr 0 failed\n");
|
||
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
#define CARD_ERASE_BLOCK_BYTES (8 * 1024 * 1024)
|
||
#define CARD_ERASE_BLOCK_SECTORS (CARD_ERASE_BLOCK_BYTES/512)
|
||
|
||
|
||
int card_erase(int erase, void *mbr_buffer)
|
||
{
|
||
char *erase_buffer;
|
||
sunxi_mbr_t *mbr = (sunxi_mbr_t *)mbr_buffer;
|
||
unsigned int erase_head_sectors;
|
||
unsigned int erase_head_addr;
|
||
unsigned int erase_tail_sectors;
|
||
unsigned int erase_tail_addr;
|
||
unsigned int skip_space[1+2*2]={0};
|
||
unsigned int from, nr;
|
||
int k, ret = 0;
|
||
int i;
|
||
|
||
//tick_printf("erase all part start\n");
|
||
if(!erase)
|
||
{
|
||
return 0;
|
||
}
|
||
erase_buffer = (char *)malloc(CARD_ERASE_BLOCK_BYTES);
|
||
if(!erase_buffer)
|
||
{
|
||
printf("card erase fail: unable to malloc memory for card erase\n");
|
||
|
||
return -1;
|
||
}
|
||
memset(erase_buffer, 0, CARD_ERASE_BLOCK_BYTES);
|
||
|
||
//erase boot0,write 0x00
|
||
card_download_boot0(32 * 1024, erase_buffer, get_boot_storage_type());
|
||
printf("erase boot0, size:32k, write 0x00\n");
|
||
|
||
for(i=1;i<mbr->PartCount;i++)
|
||
{
|
||
printf("erase %s part\n", mbr->array[i].name);
|
||
if (mbr->array[i].lenlo > CARD_ERASE_BLOCK_SECTORS * 2) // part > 16M
|
||
{
|
||
erase_head_sectors = CARD_ERASE_BLOCK_SECTORS;
|
||
erase_head_addr = mbr->array[i].addrlo;
|
||
//erase_tail_sectors = CARD_ERASE_BLOCK_SECTORS;
|
||
erase_tail_sectors = 2 * 1024 * 1024 / 512;
|
||
erase_tail_addr = mbr->array[i].addrlo + mbr->array[i].lenlo - CARD_ERASE_BLOCK_SECTORS;
|
||
}
|
||
else if (mbr->array[i].lenlo > CARD_ERASE_BLOCK_SECTORS) // 8M < part <= 16M
|
||
{
|
||
erase_head_sectors = CARD_ERASE_BLOCK_SECTORS;
|
||
erase_head_addr = mbr->array[i].addrlo;
|
||
//erase_tail_sectors = mbr->array[i].lenlo - CARD_ERASE_BLOCK_SECTORS;
|
||
erase_tail_sectors = 2 * 1024 * 1024 / 512;
|
||
erase_tail_addr = mbr->array[i].addrlo + mbr->array[i].lenlo - erase_tail_sectors;
|
||
}
|
||
else if (mbr->array[i].lenlo > 0) // 0 < part <= 8M
|
||
{
|
||
erase_head_sectors = mbr->array[i].lenlo;
|
||
erase_head_addr = mbr->array[i].addrlo;
|
||
erase_tail_sectors = 0;
|
||
erase_tail_addr = mbr->array[i].addrlo;
|
||
}
|
||
else {
|
||
//printf("don't deal prat's length is 0 (%s) \n", mbr->array[i].name);
|
||
//break;
|
||
erase_head_sectors = CARD_ERASE_BLOCK_SECTORS;
|
||
erase_head_addr = mbr->array[i].addrlo;
|
||
erase_tail_sectors = 0;
|
||
erase_tail_addr = mbr->array[i].addrlo;
|
||
}
|
||
|
||
from = mbr->array[i].addrlo + CONFIG_MMC_LOGICAL_OFFSET;
|
||
nr = mbr->array[i].lenlo;
|
||
ret = sunxi_sprite_mmc_phyerase(from, nr, skip_space);
|
||
if (ret == 0)
|
||
{
|
||
//printf("erase part from sector 0x%x to 0x%x ok\n", from, (from+nr-1));
|
||
}
|
||
else if (ret == 1)
|
||
{
|
||
for (k=0; k<2; k++)
|
||
{
|
||
if (skip_space[0] & (1<<k)) {
|
||
printf("write zeros-%d: from 0x%x to 0x%x\n", k, skip_space[2*k+1],
|
||
(skip_space[2*k+1]+skip_space[2*k+2]-1));
|
||
from = skip_space[2*k+1];
|
||
nr = skip_space[2*k+2];
|
||
if(!sunxi_sprite_mmc_phywrite(from, nr, erase_buffer))
|
||
{
|
||
printf("card erase fail in erasing part %s\n", mbr->array[i].name);
|
||
free(erase_buffer);
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (ret == -1)
|
||
{
|
||
// erase head for partition
|
||
if(!sunxi_sprite_write(erase_head_addr, erase_head_sectors, erase_buffer))
|
||
{
|
||
printf("card erase fail in erasing part %s\n", mbr->array[i].name);
|
||
free(erase_buffer);
|
||
return -1;
|
||
}
|
||
printf("erase prat's head from sector 0x%x to 0x%x\n", erase_head_addr, erase_head_addr + erase_head_sectors);
|
||
|
||
// erase tail for partition
|
||
if (erase_tail_sectors)
|
||
{
|
||
if(!sunxi_sprite_write(erase_tail_addr, erase_tail_sectors, erase_buffer))
|
||
{
|
||
printf("card erase fail in erasing part %s\n", mbr->array[i].name);
|
||
free(erase_buffer);
|
||
return -1;
|
||
}
|
||
printf("erase part's tail from sector 0x%x to 0x%x\n", erase_tail_addr, erase_tail_addr + erase_tail_sectors);
|
||
}
|
||
}
|
||
}
|
||
printf("card erase all\n");
|
||
free(erase_buffer);
|
||
|
||
//while((*(volatile unsigned int *)0) != 1);
|
||
//tick_printf("erase all part end\n");
|
||
return 0;
|
||
}
|
||
|
||
#define BOOT0_MAX_SIZE (32 * 1024)
|
||
int sunxi_card_fill_boot0_magic(void)
|
||
{
|
||
uchar buffer[BOOT0_MAX_SIZE];
|
||
boot0_file_head_t *boot0_head;
|
||
uint src_sum, cal_sum;
|
||
struct mmc *mmc0;
|
||
char debug_info[1024];
|
||
int ret = -1;
|
||
|
||
puts("probe mmc0 if exist\n");
|
||
memset(debug_info, 0, 1024);
|
||
board_mmc_pre_init(0);
|
||
mmc0 = find_mmc_device(0);
|
||
if(!mmc0)
|
||
{
|
||
strcpy(debug_info, "fail to find mmc0");
|
||
|
||
goto __sunxi_card_fill_boot0_magic_exit;
|
||
}
|
||
printf("try to init mmc0\n");
|
||
if (mmc_init(mmc0))
|
||
{
|
||
strcpy(debug_info, "MMC0 init failed");
|
||
|
||
goto __sunxi_card_fill_boot0_magic_exit;
|
||
}
|
||
memset(buffer, 0, BOOT0_MAX_SIZE);
|
||
|
||
if(mmc0->block_dev.block_read_mass_pro(mmc0->block_dev.dev, 16, BOOT0_MAX_SIZE/512, buffer) != BOOT0_MAX_SIZE/512)
|
||
{
|
||
strcpy(debug_info, "read mmc boot0 failed");
|
||
|
||
goto __sunxi_card_fill_boot0_magic_exit;
|
||
}
|
||
//compare data
|
||
boot0_head = (boot0_file_head_t *)buffer;
|
||
//fill boot0 magic
|
||
memcpy((char *)boot0_head->boot_head.magic, BOOT0_MAGIC,8);
|
||
printf("boot0_head->boot_head.magic == %s \n",(char*)boot0_head->boot_head.magic);
|
||
src_sum = boot0_head->boot_head.check_sum;
|
||
printf("src_sum = %x \n" ,src_sum);
|
||
//boot0_head->boot_head.check_sum = STAMP_VALUE;
|
||
printf("boot0_head->boot_head.length = %d \n",boot0_head->boot_head.length);
|
||
boot0_head->boot_head.check_sum = STAMP_VALUE;
|
||
cal_sum = add_sum(buffer, boot0_head->boot_head.length);
|
||
if(src_sum != cal_sum)
|
||
{
|
||
puts("boot0 addsum error\n");
|
||
|
||
return ret;
|
||
}
|
||
|
||
boot0_head->boot_head.check_sum = src_sum;
|
||
flush_cache((ulong)buffer,BOOT0_MAX_SIZE);
|
||
if(mmc0->block_dev.block_write_mass_pro(mmc0->block_dev.dev, 16, BOOT0_MAX_SIZE/512, buffer) != BOOT0_MAX_SIZE/512)
|
||
{
|
||
strcpy(debug_info, "write mmc boot0 failed");
|
||
|
||
goto __sunxi_card_fill_boot0_magic_exit;
|
||
}
|
||
|
||
ret = 0;
|
||
return ret ;
|
||
|
||
__sunxi_card_fill_boot0_magic_exit:
|
||
printf("%s\n", debug_info);
|
||
return ret ;
|
||
}
|
||
|
||
int sunxi_sprite_deal_part_from_sysrevoery(sunxi_download_info *dl_map)
|
||
{
|
||
dl_one_part_info *part_info;
|
||
int ret = -1;
|
||
int ret1;
|
||
int i = 0;
|
||
uchar *down_buff = NULL;
|
||
int rate;
|
||
|
||
if(!dl_map->download_count)
|
||
{
|
||
printf("sunxi sprite: no part need to write\n");
|
||
return 0;
|
||
}
|
||
rate = (80)/(dl_map->download_count+1);
|
||
|
||
down_buff = (uchar *)malloc(SPRITE_CARD_ONCE_DATA_DEAL + SPRITE_CARD_HEAD_BUFF);
|
||
if(!down_buff)
|
||
{
|
||
printf("sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part\n");
|
||
goto __sunxi_sprite_deal_part_err1;
|
||
}
|
||
|
||
for(part_info = dl_map->one_part_info, i = 0; i < dl_map->download_count; i++, part_info++)
|
||
{
|
||
tick_printf("begin to download part %s\n", part_info->name);
|
||
if (!strcmp("env", (const char *)part_info->name))
|
||
{
|
||
printf("env part do not need to rewrite\n");
|
||
sprite_cartoon_upgrade(20 + rate * (i+1));
|
||
continue;
|
||
}
|
||
else if (!strcmp("sysrecovery", (const char *)part_info->name))
|
||
{
|
||
printf("THIS_IMG_SELF_00 do not need to rewrite\n");
|
||
sprite_cartoon_upgrade(20 + rate * (i+1));
|
||
continue;
|
||
}
|
||
else if (!strcmp("UDISK", (const char *)part_info->name))
|
||
{
|
||
printf("UDISK do not need to rewrite\n");
|
||
sprite_cartoon_upgrade(20 + rate * (i+1));
|
||
continue;
|
||
}
|
||
else if (!strcmp("private", (const char *)part_info->name))
|
||
{
|
||
printf("private do not need to rewrite\n");
|
||
sprite_cartoon_upgrade(20 + rate * (i+1));
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
ret1 = __download_normal_part(part_info, down_buff);
|
||
if(ret1 != 0)
|
||
{
|
||
printf("sunxi sprite err: sunxi_sprite_deal_part, download normal failed\n");
|
||
goto __sunxi_sprite_deal_part_err2;
|
||
}
|
||
}
|
||
sprite_cartoon_upgrade(20 + rate * (i+1));
|
||
tick_printf("successed in download part %s\n", part_info->name);
|
||
}
|
||
|
||
ret = 0;
|
||
|
||
__sunxi_sprite_deal_part_err1:
|
||
sunxi_sprite_exit(1);
|
||
|
||
__sunxi_sprite_deal_part_err2:
|
||
|
||
if(down_buff)
|
||
{
|
||
free(down_buff);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
int __imagehd(HIMAGE tmp_himage)
|
||
{
|
||
imghd = tmp_himage;
|
||
if (imghd)
|
||
{
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
#ifdef CONFIG_SUNXI_SPINOR
|
||
extern int sunxi_sprite_setdata_finish(void);
|
||
static int __download_fullimg_part(uchar *source_buff)
|
||
{
|
||
uint tmp_partstart_by_sector;
|
||
|
||
s64 partdata_by_byte;
|
||
s64 tmp_partdata_by_bytes;
|
||
|
||
uint onetime_read_sectors;
|
||
uint first_write_bytes;
|
||
|
||
uint imgfile_start;
|
||
uint tmp_imgfile_start;
|
||
|
||
u8 *down_buffer = source_buff + SPRITE_CARD_HEAD_BUFF;
|
||
|
||
int ret = -1;
|
||
tmp_partstart_by_sector = 0;
|
||
imgitemhd = Img_OpenItem(imghd, "12345678", "FULLIMG_00000000");
|
||
if(!imgitemhd)
|
||
{
|
||
printf("sunxi sprite error: open part FULLIMG failed\n");
|
||
return -1;
|
||
}
|
||
partdata_by_byte = Img_GetItemSize(imghd, imgitemhd);
|
||
if (partdata_by_byte <= 0)
|
||
{
|
||
printf("sunxi sprite error: fetch part len FULLIMG failed\n");
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
printf("partdata hi 0x%x\n", (uint)(partdata_by_byte>>32));
|
||
printf("partdata lo 0x%x\n", (uint)partdata_by_byte);
|
||
tmp_partdata_by_bytes = partdata_by_byte;
|
||
if(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
first_write_bytes = SPRITE_CARD_ONCE_DATA_DEAL;
|
||
}
|
||
else
|
||
{
|
||
onetime_read_sectors = (tmp_partdata_by_bytes + 511)>>9;
|
||
first_write_bytes = (uint)tmp_partdata_by_bytes;
|
||
}
|
||
imgfile_start = Img_GetItemStart(imghd, imgitemhd);
|
||
if(!imgfile_start)
|
||
{
|
||
printf("sunxi sprite err : cant get part data imgfile_start FULLIMG\n");
|
||
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
tmp_imgfile_start = imgfile_start;
|
||
if(sunxi_flash_read(tmp_imgfile_start, onetime_read_sectors, down_buffer) != onetime_read_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, onetime_read_sectors);
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
tmp_imgfile_start += onetime_read_sectors;
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, onetime_read_sectors, down_buffer) != onetime_read_sectors)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error FULLIMG\n");
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
tmp_partdata_by_bytes -= first_write_bytes;
|
||
tmp_partstart_by_sector += onetime_read_sectors;
|
||
|
||
while(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
|
||
{
|
||
if(sunxi_flash_read(tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL);
|
||
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
//D′è?flash
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error FULLIMG, start 0x%x, sectors 0x%x\n", tmp_partstart_by_sector, SPRITE_CARD_ONCE_SECTOR_DEAL);
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
tmp_imgfile_start += SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
tmp_partdata_by_bytes -= SPRITE_CARD_ONCE_DATA_DEAL;
|
||
tmp_partstart_by_sector += SPRITE_CARD_ONCE_SECTOR_DEAL;
|
||
}
|
||
if(tmp_partdata_by_bytes > 0)
|
||
{
|
||
uint rest_sectors = (tmp_partdata_by_bytes + 511)>>9;
|
||
if(sunxi_flash_read(tmp_imgfile_start, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, rest_sectors);
|
||
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
if(sunxi_sprite_write(tmp_partstart_by_sector, rest_sectors, down_buffer) != rest_sectors)
|
||
{
|
||
printf("sunxi sprite error: download rawdata error FULLIMG, start 0x%x, sectors 0x%x\n", tmp_partstart_by_sector, rest_sectors);
|
||
|
||
goto __download_fullimg_part_err1;
|
||
}
|
||
}
|
||
printf("successed in writting part FULLIMG\n");
|
||
ret = 0;
|
||
|
||
__download_fullimg_part_err1:
|
||
if(imgitemhd)
|
||
{
|
||
Img_CloseItem(imghd, imgitemhd);
|
||
imgitemhd = NULL;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int sunxi_sprite_deal_fullimg(void)
|
||
{
|
||
int ret = -1;
|
||
int ret1;
|
||
uchar *down_buff = NULL;
|
||
|
||
if(sunxi_sprite_init(1))
|
||
{
|
||
printf("sunxi sprite err: init flash err\n");
|
||
return -1;
|
||
}
|
||
down_buff = (uchar *)malloc(SPRITE_CARD_ONCE_DATA_DEAL + SPRITE_CARD_HEAD_BUFF);
|
||
if(!down_buff)
|
||
{
|
||
printf("sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part\n");
|
||
|
||
goto __sunxi_sprite_deal_fullimg_err1;
|
||
}
|
||
|
||
ret1 = __download_fullimg_part(down_buff);
|
||
if(ret1 != 0)
|
||
{
|
||
printf("sunxi sprite err: sunxi_sprite_deal_part, download normal failed\n");
|
||
|
||
goto __sunxi_sprite_deal_fullimg_err2;
|
||
}
|
||
//while(*(volatile uint *)0 != 0x12);
|
||
sunxi_sprite_setdata_finish();
|
||
|
||
printf("sunxi card sprite trans finish\n");
|
||
|
||
ret = 0;
|
||
|
||
__sunxi_sprite_deal_fullimg_err1:
|
||
sunxi_sprite_exit(1);
|
||
__sunxi_sprite_deal_fullimg_err2:
|
||
if(down_buff)
|
||
{
|
||
free(down_buff);
|
||
}
|
||
return ret;
|
||
}
|
||
#endif
|
||
|
||
|
||
|