/* ************************************************************************************************************ * * function * * 函数名称: * * 参数列表: * * 返回值 : * * 说明 : * * ************************************************************************************************************ */ __s32 update_flash_write(void *pbuf, __u32 len) { __s32 ret; if(android_format == ANDROID_FORMAT_UNKONW) { ret = unsparse_probe((char *)pbuf, len, flash_start_sector); if(ret == -1) { android_format = ANDROID_FORMAT_BAD; } else { android_format = ANDROID_FORMAT_DETECT; } } if(ANDROID_FORMAT_BAD == android_format) { if(private_type == 1) { env_dram_write(pbuf, len); } else { update_flash_write_ext(pbuf, len); } } else { //unsparse_dram_write(pbuf, len); unsparse_direct_write(pbuf, len); } return 0; }
/* ************************************************************************************************************ * * 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; } } }
/* ******************************************************************************* * __flash_to_part * * Description: * void * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ static int __flash_to_part(char *name) { char *addr = trans_data.base_recv_buffer; u32 start, data_sectors; u32 part_sectors; u32 nblock = FASTBOOT_TRANSFER_BUFFER_SIZE/512; char response[68]; start = sunxi_partition_get_offset_byname(name); part_sectors = sunxi_partition_get_size_byname(name); if((!start) || (!part_sectors)) { uint addr_in_hex; int ret; printf("sunxi fastboot download FAIL: partition %s does not exist\n", name); printf("probe it as a dram address\n"); ret = strict_strtoul((const char *)name, 16, (long unsigned int*)&addr_in_hex); if(ret) { printf("sunxi fatboot download FAIL: it is not a dram address\n"); sprintf(response, "FAILdownload: partition %s does not exist", name); __sunxi_fastboot_send_status(response, strlen(response)); return -1; } else { printf("ready to move data to 0x%x, bytes 0x%x\n", addr_in_hex, trans_data.try_to_recv); memcpy((void *)addr_in_hex, addr, trans_data.try_to_recv); } } else { int format; printf("ready to download bytes 0x%x\n", trans_data.try_to_recv); format = unsparse_probe(addr, trans_data.try_to_recv, start); if(ANDROID_FORMAT_DETECT == format) { if(unsparse_direct_write(addr, trans_data.try_to_recv)) { printf("sunxi fastboot download FAIL: failed to write partition %s \n", name); sprintf(response,"FAILdownload: write partition %s err", name); return -1; } } else { data_sectors = (trans_data.try_to_recv + 511)/512; if(data_sectors > part_sectors) { printf("sunxi fastboot download FAIL: partition %s size 0x%x is smaller than data size 0x%x\n", name, trans_data.act_recv, data_sectors * 512); sprintf(response, "FAILdownload: partition size < data size"); __sunxi_fastboot_send_status(response, strlen(response)); return -1; } while(data_sectors >= nblock) { if(!sunxi_flash_write(start, nblock, addr)) { printf("sunxi fastboot download FAIL: failed to write partition %s \n", name); sprintf(response,"FAILdownload: write partition %s err", name); __sunxi_fastboot_send_status(response, strlen(response)); return -1; } start += nblock; data_sectors -= nblock; addr += FASTBOOT_TRANSFER_BUFFER_SIZE; } if(data_sectors) { if(!sunxi_flash_write(start, data_sectors, addr)) { printf("sunxi fastboot download FAIL: failed to write partition %s \n", name); sprintf(response,"FAILdownload: write partition %s err", name); __sunxi_fastboot_send_status(response, strlen(response)); return -1; } } } } printf("sunxi fastboot: successed in downloading partition '%s'\n", name); sprintf(response, "OKAY"); __sunxi_fastboot_send_status(response, strlen(response)); return 0; }